Nginx开发从入门到精通笔记——初探nginx架构(100%)
命令:
1、kill -HUP pid 从容重启nginx,也用于重新加载配置文件。
2、nginx -s reload 同1
3、nginx -s stop 停止运行
一、多进程模型VS单进程模型
单进程优点:
用于调试,方便
多进程优点:
1、高性能,充分利用cpu资源。
2、进程之间互相不影响,一个工作进程挂了不影响另外的工作进程。
3、不用复杂的线程互斥、同步。
master进程和工作进程之间通信:
使用信号量。
nginx重启过程:
1、主进程重新加载配置
2、主进程fork出新的子进程
3、主进程给老的子进程发信号,告诉它们可以退休了。
4、子进程收到信号,不再接收新的请求,并且等待当前请求结束后,就退出。
二、Nginx处理连接问题:
如何做到每个子进程都有机会处理一个连接请求?
1、父进程首先listen套接字,然后fork出子进程。
2、因为fork出来的子进程共享父进程空间,所以子进程也可以读该套接字。(fork共享文件描述符)
如果每个子进程都有机会处理一个连接请求,会不会出现并发问题?
1、不会,因为nginx给它加了锁,只有获得accept_mutex的进程才去accept该新链接。
三、事件驱动
epoll优点:
1、不需要创建线程
2、每个请求占用的内存也很少
3、没有上下文切换,事件处理非常的轻量级。【核心】并发数再多也不会导致无谓的资源浪费(上下文切换)
[测试]:在24G内存的机器上,处理的并发请求数达到过200万
四、无处不在的小优化:
1、设置worker个数=cpu核数
2、提供cpu亲和性的绑定选项
3、nginx在做4个字节的字符串比较时,会将4个字符转换成一个int型,再作比较,以减少cpu的指令数
为什么推荐设置worker的个数为cpu的核数?
避免CPU竞争CPU,带来不必要的上下文切换。
cpu核数pu亲和性:
什么是CPU亲和性?将某一个进程绑定在某一个核上,调度时候,尽量将该进程调度到该核上。
CPU亲和性有啥用?降低了进程在核之间切换,导致的高速缓存失效。。。
四、如何处理信号与定时器?
web服务器一般就是三种事件:网络事件、信号事件、定时器时间。网络事件用epoll很好解决,那么信号和定时器呢?
处理信号事件:
难点:
信号来了会中断系统调用,比如epoll_wait,这时候要继续恢复epoll_wait。
待补充。。。
处理定时器:
技巧:利用到了epoll_wait中的超时选项,搞一个红黑树来保存超时事件,每次从这棵树上搞来【下一次的超时事件离现在还有多长时间】。然后设置下一次epoll_wait多长时间。
换句话来说就是搞个红黑树保存定时事件发生时间,然后sleep一定时间,这样好理解了吧?