传输层/HTTP/Mail状态机分别对应着配置中的stream/http/mail块的配置。
- 每个处理完的请求都会记录access日志和error日志。
- 静态资源中,当内存不足以缓存住所有的文件的时候,像sendfile/AIO这些会退化为阻塞调用,所以这边需要一个线程池来处理
nginx为什么要采用多进程结构而不是多线程结构呢?
nginx为了实现高可用性和高可靠性,如果使用多线程结构,多线程结构是共享同一块内存,当某一个第三方模块导致地址越界的时候,会导致整个nginx进程全部挂掉。
master模块中,第三方通常不会加入自己的代码,master进程设计的目的是来做worker进程的管理,请求的处理是worker来做的,master进程主要做的是,监控worker进程,是否需要重新载入文件等...
worker进程间的通信都是通过共享内存来解决的。
优化点:worker进程和CPU个数保持一致;worker进程和固定CPU进行绑定,这样就可以更高的利用每个CPU上的缓存,减少缓存失效问题。
3.reload重新加载配置文件- 向master进程发送HUP信号
- master进程校验配置语法是否正确
- master进程打开新的监听端口
- master进程用新配置启动新的worker子进程
- master进程向老worker子进程发送QUIT信号
- 老worker进程关闭监听句柄,处理完当前连接后结束
- 将旧的nginx文件替换为新的nginx文件
- 向master进程发送USR2信号
- master进程修改pid文件名,加后缀.oldbin
- master进程用新的nginx文件启动master进程
- 向老的master进程发送quit信号,关闭老master进程
- 回滚:向老master发送HUP,向新master发送QUIT
问题点:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。所以老master推出后,新的master并不会退出
5.优雅的关闭worker进程- 设置定时器worker_shutdown_timeout
- 关闭监听句柄(epl_del)
- 关闭空闲连接
- 在循环中等待全部连接关闭(此阶段可能会比较耗时)
- 退出进程
- nginx首先根据本地配置的监听端口,启动服务器,等待新的事件进来,相对于epoll_wait
- 当操作系统接受到一个三次握手建立连接的报文的时候,并且处理完握手流程后,就会通知epoll_wait阻塞方法,告诉他可以往下走了,同时可以唤醒nginx的worker进程
- 操作系统会将准备好的事件放在事件队列中,从事件队列中可以获取到要处理的事件,比如TCP连接,tcp的请求报文...
- 接着会处理事件,但是在处理事件的过程中,可能会产生新的事件(比如添加定时器事件,如果连接建立成功后,1分钟没有请求,关闭连接)
每次处理100w个连接的时候,可能活跃的只有几百个,而select和poll每次去操作系统取活跃事件的时候,都需要100w个链接都扔给操作系统,由操作系统判断,哪些有事件进来了。
epoll通过红黑树和链表实现,链表里面仅仅只有活跃的连接,而针对读写事件,都是添加到红黑树中,二叉平衡树保证效率只有logn,如果不想处理读或者写事件,那么只需要去平衡二叉数中,移除对应节点即可。
链表节点的增减:当读取一个事件的时候,链表中即少一个节点,当操作系统收到网卡中发送过来的一个报文的时候,就会添加一个节点。
链表存放的是活跃事件;网卡收到报文形成事件,放入该链表;二叉树是全集事件,包括不活跃事件,相当于链表的字典,用于快速查询。
8.Nginx模块nginx可以添加一个新的模块,其中主要涉及nginx_module_t。
index:定义每个模块的顺序,index靠前的,如果和后面的模块冲突,他们会阻止后面的模块生效。
ngx_commond_t:定义了所有的配置
启停方法:最下面的7个方法(任何一个第三方模块,都有可能在master,worker执行)
type:定义模块属于哪个类型的模块,如图2所示(
NGX_CORE_MODULE衍生出NGX_HTTP_MODULE,NGX_EVENT_MODULE,NGX_STREAM_MODULE)
9.Nginx如何通过连接池处理网络请求connections代表的是连接池,read_events和write_event分别对应的可读和可写事件,和连接是通过序号对应起来的。
每个连接对应232字节大小,在nginx中每个事件对应一个ngx_events_s结构体,其大小为96个字节。所以一个连接会对应232+96 * 2个字节大小。
ngx_events_s中handler是一个回调方法(很多第三方模块把它设置为自己的方法),timer是超时
ngx_connection_s中的sent,代表这个连接上发送了多少字节数据。 pool为内存池。



