1.基于linux的epoll IO模型:
条是linux 的内核版本高于2.6
什么是epoll模型呢?
首先说下linux的 select多路利用模型:
简单来说就是使用select函数 同时监听多个客户端的连接(传递的多个文件描述符),来确认客户端连接状态是否有变化, 如果连接状态有变化(可读、可写、连接请求)则唤醒自己,然后遍历所有自己监听的连接状态,找到发生变化的连接(可以是多个),进行read操作。这种模型优点就是一个线程可监听多个连接,节省线程资源。缺点也很明显,如果有N多个连接,那么一个tpc数的包过来时就到循环N遍,效率不高。
linux epoll 模型:
和select有点相似,但不同的是在注册监听连接状态的同时还注册一个回调函数,一但连接有变化时会直接通知,调用注册的回调函数。
2.master worker进程模型
当我们启动nginx的时候,会先启动一个master进程 ,然后根据配置文件中配置的worker 进程数去启动对应worker进程,master进行和worker进行是父子关系(master 进行系统调用 fork方式产生的worker进程).所以master拥有子进程的操作权限(内存变量、函数调用、socket 文件句柄等,子进行也可以访问父进程内存空间)。
worker是真正用来处理客户端的请求的,master进程启动时负责创建一个socket文件句柄监听80端口,这时master就是启动epoll的多路复用模型。当客户端发起连接操作时 ,epoll会检测到链接状态发生了变化(第一次握手),然后自我唤醒进行回调处理(创建锁,让子进行竞争)。master不处理当前请求后续的accept。而是转交给一个worker进程处理(master会创建一个内存锁,多个worker进行竞争锁来获取处理当前请求的执行权),worker通过调用accept完成三次握手链接,然后通过accept产生的新文件句柄(数据传输过程的文件句柄)可真正用于后续读或写的操作,这里也是会使用了linux epoll,监听的是数据的读写事件。
master的其他主要任务就是收入并执行管理员的命令如reload,stop等。并且会监听worker进程的状态,如果worker挂掉,会立刻创建一个新的worker,然后把挂掉进程中的socket句柄转交给新的worker去处理(启动也一样,平滑重启)。
因为worker子进程使用epoll模型,所以并没有阻塞操作,当有读或写操作的事件时也只是进行系统空间到用户内存空间的数据拷贝。所以单线程处理效果极佳。
3.在单线程上基于协程编程模式处理请求
在一个worker进程中只有一个线程,但是要处理N多个请求,这时就需求用的协程的调用。
协程就一个比线程更小的内存模型,依附于线程。一个线程可有多个协程单元,每个协程是相互独立的一个上下方文空间。相互之单的执行切换开销也非常的小,只是内存地址的一个切换。当协程执行过程中遇到了阻塞,线线程会自动的放弃执行他,并注册epoll,立马去执行当前线程中其他不阻塞的协程。
lua也是基于协程机制。所以nginx 很适合和lua整合开发。