nginx 源码学习笔记,十八—— ngx_add_inherited_sockets 继承的sockets

之前几节有讲过多进程的创建过程和子进程所处理的事情,今天要讲一下nginx里面main函数的另一个主要的操作ngx_add_inherited_sockets。

ngx_add_inherited_sockets:服务器监听套接字的封装。

本文的主要灵感来自:http://blog.csdn.net/livelylittlefish/article/details/7277607,感谢作者分享。

在ngx_add_inherited_sockets方法内,有一个重要的结构体需要讲解——ngx_listening_s

下面主要讲解下ngx_add_inherited_sockets:

下面介绍下:ngx_set_inherited_sockets

总结:

可以看出

ngx_add_inherited_sockets:主要是通过环境变量,获取到fd的值,然后存在数组当中;

ngx_set_inherited_sockets:主要是对数组中的每一个元素进行判断是否有效,然后进行初始化操作。

附录:

TCP_DEFER_ACCEPT

我 们首先考虑的第1个选项是TCP_DEFER_ACCEPT(这是Linux系统上的叫法,其他一些操作系统上也有同样的选项但使用不同的名字)。为了理 解TCP_DEFER_ACCEPT选项的具体思想,我们有必要大致阐述一下典型的HTTP客户/服务器交互过程。请回想下TCP是如何与传输数据的目标建立连接的。在网络上,在分离的单元之间传输的信息称为IP包(或IP 数据报)。一个包总有一个携带服务信息的包头,包头用于内部协议的处理,并且它也可以携带数据负载。服务信息的典型例子就是一套所谓的标志,它把包标记代表TCP/IP协议栈内的特殊含义,例如收到包的成功确认等等。通常,在经过“标记”的包里携带负载是完全可能的,但有时,内部逻辑迫使TCP/IP协议 栈发出只有包头的IP包。这些包经常会引发讨厌的网络延迟而且还增加了系统的负载,结果导致网络性能在整体上降低。

现在服务器创建了一个套接字同时等待连接。TCP/IP式的连接过程就是所谓“3次握手”。首先,客户程序发送一个设置SYN标志而且不带数据负载的TCP包(一个SYN包)。服务器则以发出带SYN/ACK标志的数据包(一个SYN/ACK包)作为刚才收到包的确认响应。客户随后发送一个ACK包确认收到了第2个包从而结束连接 过程。在收到客户发来的这个SYN/ACK包之后,服务器会唤醒一个接收进程等待数据到达。当3次握手完成后,客户程序即开始把“有用的”的数据发送给服务器。通常,一个HTTP请求的量是很小的而且完全可以装到一个包里。但是,在以上的情况下,至少有4个包将用来进行双向传输,这样就增加了可观的延迟时间。此外,你还得注意到,在“有用的”数据被发送之前,接收方已经开始在等待信息了。

为了减轻这些问题所带来的影响,Linux(以及其他的 一些操作系统)在其TCP实现中包括了TCP_DEFER_ACCEPT选项。它们设置在侦听套接字的服务器方,该选项命令内核不等待最后的ACK包而且在第1个真正有数据的包到达才初始化侦听进程。在发送SYN/ACK包之后,服务器就会等待客户程序发送含数据的IP包。现在,只需要在网络上传送3个包 了,而且还显著降低了连接建立的延迟,对HTTP通信而言尤其如此。

对于那些支持deffered accept的操作系统,nginx会设置这个参数来增强功能,设置了这个参数,在accept的时候,只有当实际收到了数据,才唤醒在accept等待的进程,可以减少一些无聊的上下文切换,如下: