在nginx中connection就是对tcp连接的封装,其中包括连接的socket,读事件,写事件。利用nginx封装的connection,我们可以很方便的使用nginx来处理与连接相关的事情,比如,建立连接,发送与接受数据等。而nginx中的http请求的处理就是建立在connection之上的,所以nginx不仅可以作为一个web服务器,也可以作为邮件服务器。当然,利用nginx提供的connection,我们可以与任何后端服务打交道。

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

当然,nginx也是可以作为客户端来请求其它server的数据的(如upstream模块),此时,与其它server创建的连接,也封装在ngx_connection_t中。作为客户端,nginx先获取一个ngx_connection_t结构体,然后创建socket,并设置socket的属性( 比如非阻塞)。然后再通过添加读写事件,调用connect/read/write来调用连接,最后关掉连接,并释放ngx_connection_t。

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

在这里,很多人会误解worker_connections这个参数的意思,认为这个值就是nginx所能建立连接的最大值。其实不然,这个值是表示每个worker进程所能建立连接的最大值,所以,一个nginx能建立的最大连接数,应该是worker_connections * worker_processes。当然,这里说的是最大连接数,对于HTTP请求本地资源来说,能够支持的最大并发数量是worker_connections * worker_processes,而如果是HTTP作为反向代理来说,最大并发数量应该是worker_connections * worker_processes/2。因为作为反向代理服务器,每个并发会建立与客户端的连接和与后端服务的连接,会占用两个连接。

那么,我们前面有说过一个客户端连接过来后,多个空闲的进程,会竞争这个连接,很容易看到,这种竞争会导致不公平,如果某个进程得到accept的机会比较多,它的空闲连接很快就用完了,如果不提前做一些控制,当accept到一个新的tcp连接后,因为无法得到空闲连接,而且无法将此连接转交给其它进程,最终会导致此tcp连接得不到处理,就中止掉了。很显然,这是不公平的,有的进程有空余连接,却没有处理机会,有的进程因为没有空余连接,却人为地丢弃连接。那么,如何解决这个问题呢?首先,nginx的处理得先打开accept_mutex选项,此时,只有获得了accept_mutex的进程才会去添加accept事件,也就是说,nginx会控制进程是否添加accept事件。nginx使用一个叫ngx_accept_disabled的变量来控制是否去竞争accept_mutex锁。在第一段代码中,计算ngx_accept_disabled的值,这个值是nginx单进程的所有连接总数的八分之一,减去剩下的空闲连接数量,得到的这个ngx_accept_disabled有一个规律,当剩余连接数小于总连接数的八分之一时,其值才大于0,而且剩余的连接数越小,这个值越大。再看第二段代码,当ngx_accept_disabled大于0时,不会去尝试获取accept_mutex锁,并且将ngx_accept_disabled减1,于是,每次执行到此处时,都会去减1,直到小于0。不去获取accept_mutex锁,就是等于让出获取连接的机会,很显然可以看出,当空余连接越少时,ngx_accept_disable越大,于是让出的机会就越多,这样其它进程获取锁的机会也就越大。不去accept,自己的连接就控制下来了,其它进程的连接池就会得到利用,这样,nginx就控制了多进程间连接的平衡了。

ngx_accept_disabled = ngx_cycle->connection_n / 8- ngx_cycle->free_connection_n;if (ngx_accept_disabled > 0) {ngx_accept_disabled--;} else {if (ngx_trylock_accept_mutex(cycle) == NGX_ERROR) {return;}if (ngx_accept_mutex_held) {flags |= NGX_POST_EVENTS;} else {if (timer == NGX_TIMER_INFINITE|| timer > ngx_accept_mutex_delay){timer = ngx_accept_mutex_delay;}}
}

好了,连接就先介绍到这,本章的目的是介绍基本概念,知道在nginx中连接是个什么东西就行了,而且连接是属于比较高级的用法,在后面的模块开发高级篇会有专门的章节来讲解连接与事件的实现及使用。

nginx基础概念(100%)之connection相关推荐

  1. nginx基础概念(100%)之lingering_close

    lingering_close,字面意思就是延迟关闭,也就是说,当nginx要关闭连接时,并非立即关闭连接,而是先关闭tcp连接的写,再等待一段时间后再关掉连接的读.为什么要这样呢?我们先来看看这样一 ...

  2. nginx基础概念(100%)之keepalive

    当然,在nginx中,对于http1.0与http1.1也是支持长连接的.什么是长连接呢?我们知道,http请求是基于TCP协议之上的,那么,当客户端在发起请求前,需要先与服务端建立TCP连接,而每一 ...

  3. nginx基础概念(100%)之request

    这节我们讲request,在nginx中我们指的是http请求,具体到nginx中的数据结构是ngx_http_request_t.ngx_http_request_t是对一个http请求的封装. 我 ...

  4. nginx基础概念(100%)之pipe

    在http1.1中,引入了一种新的特性,即pipeline.那么什么是pipeline呢?pipeline其实就是流水线作业,它可以看作为keepalive的一种升华,因为pipeline也是基于长连 ...

  5. 私钥经过哈希计算可以产生公钥_「区块链基础概念100」:公钥和私钥 | 027

    免责声明:本文旨在传递更多市场信息,不构成任何投资建议.文章仅代表作者观点,不代表火星财经官方立场. 小编:记得关注哦 投资区块链,猛戳:火星财经App下载 来源:学习区块链 原文标题:「区块链基础概 ...

  6. nginx基础概念及配置解析

    nginx入门与实战 网站服务 想必我们大多数人都是通过访问网站而开始接触互联网的吧.我们平时访问的网站服务 就是 Web 网络服务,一般是指允许用户通过浏览器访问到互联网中各种资源的服务. Web ...

  7. Nginx基础应用配置小结 - 运维笔记

    Nginx基础应用配置小结 - 运维笔记 在linux系统下使用nginx作为web应用服务,用来提升网站访问速度的经验已五年多了,今天在此对nginx的使用做一简单总结. 一.nginx服务简介 N ...

  8. gRPC 基础概念详解

    作者:jasonzxpan,腾讯 IEG 运营开发工程师 gRPC (gRPC Remote Procedure Calls) 是 Google 发起的一个开源远程过程调用系统,该系统基于 HTTP/ ...

  9. 302状态码_HTTP协议详解(基础概念 方法 状态码 首部 连接 Cookie 新特性 安全)

    一 .基础概念 URI URI 包含 URL 和 URN. 请求和响应报文 1. 请求报文 2. 响应报文 二.HTTP 方法 客户端发送的 请求报文 第一行为请求行,包含了方法字段. GET 获取资 ...

最新文章

  1. servlet工作原理_Servlet 生命周期、工作原理
  2. Java知多少(23)类的基本运行顺序
  3. 看云原生实战就来这里,侬晓得伐?
  4. spring的aop的动态代理机制都有哪些_Spring学习(4):Spring AOP
  5. MongoDB 增量备份方案
  6. hibernate在分层架构中修改数据(update)时遇到的问题!!
  7. OpenGL入门-1
  8. python图像处理:一福变五福
  9. 多线程TCP客户端的设计
  10. django项目-自助饮料机
  11. 运用frame、frameset框架不显示问题
  12. linux windos 设计理念,Windows 20 概念设计
  13. 闲聊2022卡塔尔世界杯
  14. 05.数据的深度分析(数据挖掘、机器学习)--《数据科学概论》
  15. 中型B2C电商行业BI系统推荐?
  16. 学习linux的网站
  17. 非自锁单按钮控制启停电路
  18. MTK平台DDR降频(调整频率)的方法
  19. 酷讯的今天应引起创业者警醒
  20. 福建程序员行业技术微信交流群,福建的小伙伴看过来了!

热门文章

  1. oracle分组关联统计,没有记录则显示0
  2. mysql cache lock_MySQL:query cache lock
  3. 中python执行shell_IPython,在探索中学习编程
  4. 排序算法(1)----选择排序算法
  5. 开源java项目_请问有哪些开源java项目值得学习的?学习完了容易找工作的?
  6. pojo和java对象_java对象 POJO和JavaBean的区别
  7. arduino 蓝牙示例_,arduino 蓝牙例子,
  8. Code Access Security (CAS)
  9. HDU 2154 跳舞毯
  10. 20个使用Bootstrap制作的前端框架网站案例