2018_03_15 Nginx:nginx对connection的控制(二)

在nginx中connection就是对tcp连接的封装,其中包括连接的socket,读事件,写事件。

nginx是如何处理一个连接的?
nginx在启动时,会解析配置文件,得到需要监听的端口和ip地址,然后在nginx的master进程里面,初始化好这个监控的socket(创建socket,设置addrreuse等选项,绑定到指定的ip地址端口,再listen),然后再fork出多个子进程出来,子进程会竞争accept新的连接,此时,客户端就可以向nginx发起连接了,当客户端与服务端通过三次握手建立好一个连接后,nginx的某一个子进程会accept成功,得到这个建立好的连接的socket,然后创建nginx对连接的封装,即ngx_connection_t结构体,接着,设置读写事件处理函数并添加读写事件来与客户端进行数据的交换,最后,nginx或客户端来主动关闭连接。

在nginx中,每个进程会有一个连接数的最大上限,这个上限与系统对fd的限制不同,在linux操作系统中,通过ulimit -n,可以获得一个进程所能够打开的fd的最大数,即nofile,因为每个socket连接会占用一个fd,所以这也会限制进程的最大连接数,进而直接影响到程序所能支持的最大并发数,当fd用完后,再创建爱你socket时,就会失败。nginx通过设置worker_connectons来设置每个进程支持的最大连接数。如果这个值大于nofile,那么实际的最大连接数就是nofile,因为这是进程所能支撑的最大连接数,此时nginx会有警告。所以nginx在实现时,是通过一个连接池来管理的,每个worker进程都有一个独立的连接池,连接池的大小是worker_connections。这里的连接池里面保存的不是真实的连接,它只是一个worker_connections大小的一个ngx_connection_t结构的数组。并且,nginx会通过一个链表free_connections来保存所有的空闲ngx_connection_t,每次获取一个连接时,就从空闲连接链表中获取一个,用完后,再放回空闲连接链表里面。

worker_connections是表示每个worker进程所能建立连接的最大值,所以一个nginx能建立的最大连接数,应该是worker_connections * worker_processes。这是nginx作为服务器来讲,http请求本地资源来说,但是如果是HTTP作为反向代理来说,最大并发数量应该是worker_connections * worker_processes/2。因为作为反向代理服务器,每个并发会建立与客户端的连接和与后端服务的连接,会占用两个连接。

当一个客户端连接进来时,多个空闲的进程竞争这个连接,很有可能会某一个进程的空闲连接都用光了,而其他空闲进程却抢不到连接,没有处理的机会,对于这种情况应该怎么解决呢?

nginx的各个子进程在处理连接之前,会先打开accept_mutex选项,只有获得了accept_mutex选项的进程才有机会去竞争连接。(此处可以联想多线程,但是又与多线程不同,多线程抢一个锁,只能有一个线程是执行过程中,但是这里的标识可以由多个子进程获取到)。因为这个机制,nginx有下面这个处理方案,nginx使用一个叫ngx_accept_disabled的变量来控制是否去竞争accept_mutex锁。多个子进程要抢连接之前,会通过一个公式,ngx_accept_disabled = nginx的单个子进程的所有连接总数的八分之一 - 剩下的空闲连接数量。(因为nginx的单个子进程的所有连接总数的八分之一这个数值是一个固定值,所以当剩下的空闲连接数量小于这个值时,这个变量的值一定是大于0的,nginx中就限定,当这个值大于0时,不允许去尝试获取accept_mutex锁,并且将这个变量值减1,每次其他的子进程抢到连接后都会减1,直到这个计算出的变量值小于0时,再去参与连接竞争)。

通过这种方式,很显然可以得出结论,当空余连接越少时,ngx_accept_disable越大,放弃抢连接的时间越多,其他进程获取连接的机会就越大,不去竞争,自然连接的控制就做到了,其他的进程连接池就会得到利用,这样nginx就控制了多进程间连接的平衡了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值