一.概述node
Node.js 是一种创建在Google Chrome’s v8 engine上的 non-blocking (非阻塞), event-driven (基于事件的) I/O平台.数据库
以事件驱动为核心,单线程,单进程。Node.js 最大的特色就是采用异步式 I/O 与事件驱动的架构设计。对于高并发的解决方案,传统的架构是多线程模型,也就是为每一个业务逻辑提供一个系统线程,经过系统线程切换来弥补同步式 I/O 调用时的时间开销。Node.js 使用的是单线程模型,对于全部 I/O 都采用异步式的请求方式,避免了频繁的上下文切换。Node.js 在执行的过程当中会维护一个事件队列,程序在执行时进入事件循环等待下一个事件到来,每一个异步式 I/O 请求完成后会被推送到事件队列,等待程序进程进行处理。事件驱动机制是Node.js经过内部单线程高效率地维护事件循环队列来实现的,没有多线程的资源占用和上下文切换,这意味着面对大规模的http请求,Node.js凭借事件驱动搞定一切。由于Node是基于事件驱动和无阻塞的,因此很是适合处理并发请求。能够经过运行多个Node.js进程的方式来有效利用多个CPU。编程
1.在Linux下,node.js靠libev和libeio配合使用来实现异步I/O。api
(1).什么是libev?服务器
• libev是一个事件驱动库,提供高性能事件循环网络
• 主要用于事件驱动的网络编程多线程
(2).什么是libeio?架构
libeio为C提供异步版本的POSIX API并发
• 主要提供文件I/O操做异步
• 异步操做经过线程实现
• libeio仅依赖pthread,跨平台能力很是好
• 能够和任何事件库配合使用,好比libev 。
(3).为何不用libev实现异步文件操做?
对于Regular File 来讲,是不可以用采用 poll/epoll 的,即O_NOBLOCK 方式对于传统文件句柄是无效的,也就是说咱们的 open ,read, mkdir 之类的Regular File操做一定会致使阻塞.
2.Windows有一种独有的内核异步IO方案:IOCP。IOCP的思路是真正的异步I/O方案,调用异步方法,而后等待I/O完成通知。IOCP内部依旧是经过线程实现,不一样在于这些线程由系统内核接手管理。IOCP的异步模型与Node.js的异步调用模型已经十分近似。
3.因为Windows平台和*nix平台的差别,Node.js提供了libuv来做为抽象封装层,使得全部平台兼容性的判断都由这一层次来完成,保证上层的Node.js与下层的libeio/libev及IOCP之间各自独立。Node.js在编译期间会判断平台条件,选择性编译unix目录或是win目录下的源文件到目标程序中。
对于 POSIX①操做系统,libuv 经过封装 libev 和 libeio 来利用 epoll 或 kqueue。而在 Windows 下,libuv 使用了 Windows 的 IOCP(Input/Output Completion Port,输入输出完成端口)机制,以在不一样平台下实现一样的高性能。
① POSIX(Portable Operating System Interface)是一套操做系统 API 规范。通常而言,遵照 POSIX 规范的操做系统指的是 UNIX、Linux、Mac OS X 等。
下面是Node.JS架构示意图
Node.js 的异步机制是基于事件的,全部的磁盘 I/O、网络通讯、数据库查询都以非阻塞的方式请求,返回的结果由事件循环来处理。图1-1 描述了这个机制。Node.js 进程在同一时刻只会处理一个事件,完成后当即进入事件循环检查并处理后面的事件。这样作的好处是,CPU 和内存在同一时间集中处理一件事,同时尽量让耗时的 I/O 操做并行执行。对于低速链接攻击,Node.js 只是在事件队列中增长请求,等待操做系统的回应,于是不会有任何多线程开销,很大程度上能够提升 Web 应用的健壮性,防止恶意攻击。
图1-1 事件循环
以在Windows平台下的实现中,启动Node.js时,便建立了一个基于IOCP的事件循环loop,并一直处于执行状态。
uv_run(uv_default_loop());
每次循环中,它会调用IOCP相关的GetQueuedCompletionStatus方法检查是否线程池中有执行完的请求,若是存在,poll操做会将请求对象加入到loop的pending_reqs_tail属性上。 另外一边这个循环也会不断检查loop对象上的pending_reqs_tail引用,若是有可用的请求对象,就取出请求对象的result属性做为结果传递给oncomplete_sym执行,以此达到调用JavaScript中传入的回调函数的目的。 至此,整个异步I/O的流程完成结束。
事件循环和请求对象构成了Node.js的异步I/O模型的两个基本元素,这也是典型的消费者生产者场景。在Windows下经过IOCP的GetQueuedCompletionStatus、PostQueuedCompletionStatus、QueueUserWorkItem方法与事件循环实。对于*nix平台下,这个流程的不一样之处在与实现这些功能的方法是由libeio和libev提供。