传输层/HTTP/Mail状态机分别对应着配置中的stream/http/mail块的配置。

nginx为什么要采用多进程结构而不是多线程结构呢?
nginx为了实现高可用性和高可靠性,如果使用多线程结构,多线程结构是共享同一块内存,当某一个第三方模块导致地址越界的时候,会导致整个nginx进程全部挂掉。
master模块中,第三方通常不会加入自己的代码,master进程设计的目的是来做worker进程的管理,请求的处理是worker来做的,master进程主要做的是,监控worker进程,是否需要重新载入文件等...
worker进程间的通信都是通过共享内存来解决的。
优化点:worker进程和CPU个数保持一致;worker进程和固定CPU进行绑定,这样就可以更高的利用每个CPU上的缓存,减少缓存失效问题。


问题点:一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。所以老master推出后,新的master并不会退出


每次处理100w个连接的时候,可能活跃的只有几百个,而select和poll每次去操作系统取活跃事件的时候,都需要100w个链接都扔给操作系统,由操作系统判断,哪些有事件进来了。
epoll通过红黑树和链表实现,链表里面仅仅只有活跃的连接,而针对读写事件,都是添加到红黑树中,二叉平衡树保证效率只有logn,如果不想处理读或者写事件,那么只需要去平衡二叉数中,移除对应节点即可。
链表节点的增减:当读取一个事件的时候,链表中即少一个节点,当操作系统收到网卡中发送过来的一个报文的时候,就会添加一个节点。
链表存放的是活跃事件;网卡收到报文形成事件,放入该链表;二叉树是全集事件,包括不活跃事件,相当于链表的字典,用于快速查询。

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)


connections代表的是连接池,read_events和write_event分别对应的可读和可写事件,和连接是通过序号对应起来的。

每个连接对应232字节大小,在nginx中每个事件对应一个ngx_events_s结构体,其大小为96个字节。所以一个连接会对应232+96 * 2个字节大小。
ngx_events_s中handler是一个回调方法(很多第三方模块把它设置为自己的方法),timer是超时
ngx_connection_s中的sent,代表这个连接上发送了多少字节数据。 pool为内存池。
