您的位置:首页 > Web前端 > Node.js

深入浅出node.js:3 异步I/O

2018-01-08 20:02 489 查看
   Web 2.0中的AJAX

   异步早就在OS的中,通过信号量、消息等方式。意外的是,编程语言中不多见,主要原因是程序员不太适合通过异步来进行程序设计。

   PHP屏蔽了异步,优点十分明显,利于编写业务逻辑;缺点是在复杂的网络中阻塞导致无法更好地并发。

3.1 为什么要异步I/O

    用户体验:消除UI阻塞的现象

    资源分配:利用单线程,远离多线程死锁、状态同步等问题;利用异步IO,让单线程远离阻塞,以更好地使用CPU。

3.2 异步IO实现现状

     轮询技术主要有以下:

     read:重复调用来检查IO的状态
     select:对文件描述符上的事件状态来进行判断。采用一个1024长度的数组来存储状态,所以它最多可以同时检查1024个文件描述符。
     poll:较select有所改进,采用链表的方式和避免不需要的检查,性能还是低
     epoll:Linux下效率最高的I/O事件通知机制,如果没有检查到I/O事件,将会进行休眠,直到事件发生将它唤醒。而不是遍历查询,不会浪费CPU
     kqueue:仅在FreeBSD系统

     轮询技术满足了非阻塞IO确保获取完整数据的需求,但对于应用程序而言,仍然只能算是一种同步。

     理想的非阻塞异步I/O:

     现实的异步I/O:glibc中的AIO是典型的线程池模拟异步I/O。libev的作者重新实现了一个异步I/O的库:libeio,实质上是采用线程池与阻塞I/O模拟异步I/O。最初Node采用它,v0.9.3中自行实现。

3.3 Node的异步I/O

     1、事件循环:while(true)的循环,每执行一次循环体的过程称为Tick,查看是否有事件待处理。

     2、观察者:判断是否有事件需要处理?

     3、请求对象:

     4、执行回调:

3.4 非I/O的异步API

      1、定时器:     

3.5 事件驱动与高性能服务器

      通过主循环加事件触发的方式来运行程序


   

    几种经典的服务器模型

同步式:一次只能处理一个请求,并且其余请求都处于等待状态
每进程/每请求:为每个请求启动一个进程,这样可以处理多个请求,但是它不具备扩展性,因为系统资源只有那么多。
每线程/每请求:为每个请求启动一个线程来处理。尽管线程比进程要轻量,但是由于每个线程都占用一定内存,当大并发请求到来时,内存将会很快用光,导致服务器缓慢。

     而Node通过事件驱动的方式处理请求,无须为每个请求创建额外的对应线程,可以省掉创建线程和销毁线程的开销,同时操作系统在调度任务时因为线程较少,上下文切换的代价很低。这使得服务器能够有条不紊地处理请求,即使在大量链接的情况下,也不受线程上下文切换开销的影响,这是Node高性能的一个原因。

      知名服务器Nginx,也摒弃了多线程的方式,采用了和Node相同的事件驱动。如今,Nginx大有取代Apache之势。Node具有与Nginx相同的特性,不同之处在于Nginx采用纯C写成,性能较高,但是它仅适合于做Web服务器,用于反向代理或负载均衡等服务,在处理具体业务方面较为欠缺。Node则是一套高性能的平台,可以利用它构建与Nginx相同的功能,也可以处理各种具体业务,而且与背后的网络保存异步畅通。两者相比,Node没有Nginx在Web服务器方面那么专业,但场景更大,自身性能也不错。在实际项目中,我们可以结合它们各自优点,以达到应用的最优性能。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: