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一定时间,这样好理解了吧?