关于网站建设与发布的书籍,做招聘网站的背景图片,wordpress能改用户名吗,个人网站作品nginx中http模块使用http长连接的相关配置(主要是keepalive指令)和http长连接的原理解释。1、http长连接1.1 预备知识连接管理是一个 HTTP 的关键话题#xff1a;打开和保持连接在很大程度上影响着网站和 Web 应用程序的性能。在 HTTP/1.x 里有多种模型#xff1a;短连接, 长… nginx中http模块使用http长连接的相关配置(主要是keepalive指令)和http长连接的原理解释。1、http长连接1.1 预备知识连接管理是一个 HTTP 的关键话题打开和保持连接在很大程度上影响着网站和 Web 应用程序的性能。在 HTTP/1.x 里有多种模型短连接, 长连接, 和 HTTP 流水线。在解释这三种模型之前我们需要先明确一些前提知识•HTTP是属于应用层(七层)的协议同时它的传输层(四层)使用的是TCP协议那么也就是说HTTP的长连接和短连接其本质就是TCP的长连接和短连接•HTTP是一个无状态的面向连接的协议(使用TCP面向连接、可靠传输)指的是协议对于事务处理没有记忆能力服务器不知道客户端是什么状态无状态不代表HTTP不能保持TCP连接更不能代表HTTP使用的是UDP协议(无连接)•TCP建立连接和断开连接是需要三握四挥的由于这个属于计算机网络基本知识所以原理这里不再赘述接下来我们开始解释。1.2 HTTP短连接模型在早期HTTP 使用一个简单的模型来处理这样的连接。这些连接的生命周期是短暂的每发起一个请求时都会创建一个新的连接并在收到应答时立即关闭。这就是类似上面说的三次握手在互联网发展的早期一个网页的资源并没有现在这么多很多可能只是一个简单的静态页面而已所以这样的模型显然很OK。客户端获取完所需资源之后就断开连接不再占用服务器的资源。套用TCP连接的三握四挥的模型来举例三次握手A→B今晚下班一起吃饭吗B→A好的今晚下班一起吃饭。A→B好的我知道你答应我今晚下班一起吃饭的邀请了。然后开始去吃饭吃完饭到了两个人需要各自回家的时候四次挥手A→B我吃完饭准备走了B→A等一下我快吃完了B→A好了我吃完了可以走了A→B好的我知道你吃完了我们可以走了然后两人吃完饭就各回各家了HTTP 短连接模型是最早期的模型也是 HTTP/1.0 的默认模型。每一个 HTTP 请求都由它自己独立的连接完成这意味着发起每一个 HTTP 请求之前都会有一次 TCP 握手而且是连续不断的。实际上TCP 协议握手本身就是耗费时间的所以 TCP 可以保持更多的热连接来适应负载。短连接破坏了 TCP 具备的能力新的冷连接降低了其性能。在 HTTP/1.0 中如果没有指定 Connection协议头或者是值被设置为 close就会启用短连接模型要在 HTTP/1.0 中启用长连接模型需要在协议头中指定Connection: Keep-Alive 不过并不建议这样操作。而在 HTTP/1.1 中默认使用长连接模型只有当 Connection被设置为 close 时才会用到这个短连接模型协议头都不用再去声明它(但是一般还是会把它加上以防万一因为某种原因要退回到 HTTP/1.0 )。1.3 HTTP长连接模型后来网页需要请求的资源越来越多短连接模型显然已经十分吃力了。因为短连接有两个比较大的问题创建新连接耗费的时间尤为明显(三次握手很耗费时间)另外 TCP 连接的性能只有在该连接被使用一段时间后(热连接)才能得到改善。因此在HTTP/1.1中引入了长连接模型和流水线模型。在 HTTP/1.1 之前长连接也被称为keep-alive 连接。一个长连接会保持一段时间重复用于发送一系列请求节省了新建 TCP 连接握手的时间还可以利用 TCP 的性能增强能力。当然这个连接也不会一直保留着连接在空闲一段时间后会被关闭(服务器可以使用 Keep-Alive 协议头来指定一个最小的连接保持时间)。套用上面的例子来进一步解释三次握手A→B今晚下班一起吃饭吗B→A好的今晚下班一起吃饭。A→B好的我知道你答应我今晚下班一起吃饭的邀请了。然后开始去吃饭但是这时吃完饭就不是马上四次挥手断开连接AB两人还顺便去逛街、看电影(相当于省去了三次握手使用已建立的连接来传输多个资源)此处省略四次挥手最后两人就各回各家了长连接也还是有缺点的也就是前面提到的资源占用问题就算是在空闲状态它还是会消耗服务器资源也更容易被DDoS攻击。本质上长连接是因为不断地三次握手建立连接消耗的资源要大于维持连接所需要的资源才使用的如果服务器处于高负载时段或者被DDoS可以使用非长连接即尽快关闭那些空闲的连接也能对性能有所提升。1.4 HTTP流水线模型流水线模型的实现要复杂很多而已效果也并不是特别好主要还要考虑到各种兼容性所以默认是不启用这个流水线模型的而在HTTP/2中流水线已经被更好的算法给代替如multiplexing。默认情况下HTTP 请求是按顺序发出的。下一个请求只有在当前请求收到应答过后才会被发出。由于会受到网络延迟和带宽的限制在下一个请求被发送到服务器之前可能需要等待很长时间。流水线是在同一条长连接上发出连续的请求而不用等待应答返回。这样可以避免连接延迟。理论上讲性能还会因为两个 HTTP 请求有可能被打包到一个 TCP 消息包中而得到提升。就算 HTTP 请求不断的继续尺寸会增加但设置 TCP 的 MSS(Maximum Segment Size) 选项仍然足够包含一系列简单的请求。并不是所有类型的 HTTP 请求都能用到流水线只有 idempotent方式比如 GET、HEAD、PUT和 DELETE能够被安全的重试因为有故障发生时流水线的内容要能被轻易的重试即出现了问题重试的成本要尽可能低否则还不如使用长连接模型。正确的实现流水线是复杂的传输中的资源大小多少有效的 RTT 会被用到还有有效带宽流水线带来的改善有多大的影响范围。不知道这些的话重要的消息可能被延迟到不重要的消息后面。这个重要性的概念甚至会演变为影响到页面布局因此 HTTP 流水线在大多数情况下带来的改善并不明显。此外流水线受制于 HOL 问题。摘自wiki队头阻塞(Head-of-line blocking或缩写为HOL blocking)在计算机网络[1]的范畴中是一种性能受限的现象。它的原因是一列的第一个数据包(队头)受阻而导致整列数据包受阻。例如它有可能在缓存式输入的交换机中出现有可能因为传输顺序错乱而出现亦有可能在HTTP流水线中有多个请求的情况下出现。我们还是使用上面的例子来进行解释这次的握手请求就变了A一次向B发出了三个请求三次握手A→B今晚下班一起吃饭、逛街、看电影吗B→A好的今晚下班一起吃饭、逛街、看电影。A→B好的我知道你答应我今晚下班一起吃饭、逛街、看电影的邀请了。实际上这样子是有很大的风险的如果是按照长连接模型A可以根据B在吃饭的时候的反应来决定要不要继续去逛街看电影也就是如果传输完了一次数据之后还保持连接就继续传输万一连接突然断开或者是不稳定那可能就要重新建立连接。(万一B在吃饭的时候吃的不开心不想继续逛街看电影那就等下次再吃饭逛街看电影)但是如果按照流水线模型A一次发送三个请求虽然发送请求的时候省事儿了(三次握手的时候TCP打包传输请求更省事)但是谁也不知道吃饭逛街看电影的过程中会发生什么意外时间越长越不稳定而且还容易出现万一B想减肥不想吃饭只想逛街看电影的情况呢(HOL问题)最后这里补充一张图片来对比三种模型之间的差别2、Nginx中的keepalive指令当我们配置Nginx作为代理服务器的时候想要支持HTTP长连接需要client到Nginx和Nginx到server都是长连接因为此时Nginx既是client的server也是server的client。了解了上面的原理之后Nginx中的keepalive指令我们就非常好理解了相关的指令主要有三个我们逐个进行解释2.1 keepaliveSyntax: keepalive connections;Default: —Context: upstreamThis directive appeared in version 1.1.4.在upstream模块中配置启用连接到upstream中的服务器的缓存connections参数的主要作用是设定每个Nginx的单个worker进程(each worker process)对于upstream中的server的最大空闲连接数当超过该数字的时候会关闭使用得最少的连接。•对于HTTP应将proxy_http_version指令设置为“ 1.1”并且应清除Connection标题字段•对于FastCGI服务器需要设置fastcgi_keep_conn以启用keepalive连接upstream http_backend {server 127.0.0.1:8080;keepalive 16;}server { location /http/ {proxy_pass http://http_backend;proxy_http_version 1.1; proxy_set_header Connection ; } lcaotion /FastCGI/ {fastcgi_pass fastcgi_backend;fastcgi_keep_conn on; }}需要注意的是keepalive指令并不会限制Nginx的所有worker进程能开启的连接到upstream服务器中的连接总数(total number)。也就是如果设得太大了会导致过多的空闲连接占满了upstream中的server资源导致新的连接无法建立因此这个数值的设定需要根据worker进程数量来调整。2.2 keepalive_requestsSyntax: keepalive_requests number;Default: keepalive_requests 100;Context: upstreamThis directive appeared in version 1.15.3.keepalive_requests设定可以通过一个连接(connection)发送的请求(request)数量超过最大请求数量之后该连接会被关闭。为了释放每个连接的内存分配定期关闭连接是很有必要的。因此不建议将keepalive_requests设定过大否则可能会导致过高的内存占用。2.3 keepalive_timeoutSyntax: keepalive_timeout timeout;Default: keepalive_timeout 60s;Context: upstreamThis directive appeared in version 1.15.3.设定连接超时时间在此设定的时间内client与upstream中的server的空闲keepalive连接将保持打开状态(open)。此外虽然官方文档说的默认值是60s但是1.17.9版本的Nginx在安装之后配置文件nginx.conf上面设定的是65s。References[1] 计算机网络: https://zh.wikipedia.org/wiki/计算机网络