【Nginx08】Nginx学习:HTTP核心模块(五)长连接与连接处理

这篇具有很好参考价值的文章主要介绍了【Nginx08】Nginx学习:HTTP核心模块(五)长连接与连接处理。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

Nginx学习:HTTP核心模块(五)长连接与连接处理

HTTP 基础知识大家掌握的怎么样呀?对于长连接这一块的内容应该也不是什么新鲜东西了吧。毕竟 HTTP1.1 都已经发布这么久了。今天主要来看的就是长连接相关的配置,另外还会介绍几个和连接有关的内容。同时,今天的内容除了 HTTP 外,还需要一点 TCP 的知识。没办法,毕竟 Ngxin 本身就是一个网络代理服务器软件,离不开的就是各种网络相关的知识。相信大家肯定没问题的,毕竟很早前在短视频中就说过,基础能比我差的程序员估计在全国范围内都找不到几个了。

但是不要脸和硬着头皮啃的水平咱还是有的,因此,如果有遗漏或错误的地方,也恳请各位大佬在评论区指出。

好了,不多废话了,进入主题吧。

长连接

关于长连接的知识,属于 HTTP 的基础知识了,咱们不多说,不了解的小伙伴可以去查阅下相关资料。简单来说,一次 HTTP 连接,就要经历 TCP 的三次握手四次挥手,毕竟它是处于网络的第七层,同时也是基于第四层的 TCP 来实现的。如果请求很多,需要不停地建立 TCP 连接,效率明显下降。而长连接则是一次连接后保持这个连接一段时间,如果有其它的请求就可以复用这条连接,从而减少网络连接开销,提升效率。比如很多门户或者电商站,一打开就是一大堆的 JS、图片之类的请求。如果每一个都要单独建立连接,势必会影响页面的整体打开速度。

同时,在进行反向代理的时候,也可以启用长连接功能,减少后端代理的连接次数。反向代理相关的配置我们在后面学习反向代理相关的内容时再说,现在学习的主要是针对 http、server、location 模块的长连接配置。

在 Nginx 中,有完整的长连接配置。

keepalive_disable

指定哪些浏览器不使用长连接功能,或者说是针对行为异常的浏览器关闭长连接功能。

keepalive_disable none | browser ...;

默认 msie6 , 值为 msie6 表示在遇到POST请求时,关闭与老版本 MSIE 浏览器建立长连接。 值为 safari 表示在遇到 Mac OS X 和类 Mac OS X 操作系统下的 Safari 浏览器和类 Safari 浏览器时,不与浏览器建立长连接。 值为none表示为所有浏览器开启长连接功能。

在 nginx 1.1.18 版本及以前,safari 将匹配所有操作系统上的 Safari 和类 Safari 浏览器,并默认不与这些浏览器建立长连接。

我本地是 Mac 电脑,因此,直接设置一个 safari 的配置。

http {
  ……
  keepalive_disable safari;
 ……
}

配置完成后,使用 Safari 和 Chrome 分别测试,可以看到 Safari 的 Response Header 中的 Connection 的值变成了 close ,而 Chrome 还是正常的 keep-alive 。

keepalive_requests

设置通过一个长连接可以处理的最大请求数。 请求数超过此值,长连接将关闭。

keepalive_requests number;

在版本1.19.10之前,默认值为100,现在默认值是 1000 。定期关闭连接对于释放每个连接的内存分配是必要的。因此,使用过高的最大请求数可能会导致内存使用过多,因此不建议使用。

我们直接配置一个,将它的 number 设置为 2 ,然后建立一个 html 页面以及一堆空的 js 文件。

// nginx.conf
http {
  ……
  keepalive_requests 2;
 ……
}

// testkeepalive1.html
~
~
"testkeepalive1.html" 23L, 461C                                                                                                                                                  20,19-26      All
<!DOCTYPE html>
<html>
<head>
<title>Welcome to nginx!</title>
<style>
html { color-scheme: light dark; }
body { width: 35em; margin: 0 auto;
font-family: Tahoma, Verdana, Arial, sans-serif; }
</style>
</head>
<body>
<h1>Welcome to nginx!</h1>

This is testkeepalive1.html

<script src="js1/1.js"></script>
<script src="js1/2.js"></script>
<script src="js1/3.js"></script>
<script src="js1/4.js"></script>
<script src="js1/5.js"></script>

</body>
</html>

好了,现在访问 http://192.168.56.88/testkeepalive1.html 页面,查看所有的请求,目前我们算上这个 html 页面,一共会有 6 个请求。你会发现有的请求的 Connection 会变成 Close ,也就是说一条长连接在请求数量达到设置的值之后就断了,然后又是一个新的请求连接。

一般情况下不需要刻意设置这个值,上面文档的说明中也说过了使用过高的最大请求数可能会导致内存使用过多,正常来说 1000 已经相当够用了,即使是淘宝这样的网站,首页上的请求数也没多少,毕竟大家还会合并请求及图片来进行连接的优化。

keepalive_time

限制通过一个保持活动连接处理请求的最长时间。

keepalive_time time;

达到此时间后,连接在后续请求处理后关闭,默认值是 1h 。它是 Nginx 1.19.10 之后新出的配置,咱们就不做详细的测试了,如果想要测试的同学,可以根据下面的 keepalive_timeout 测试,然后访问一个动态能够 sleep 的请求路径,让 sleep 时间超过这个配置的时间,接着使用一个静态页面来定时发送 ajax 请求查看连接复用情况。比较麻烦,日常估计使用的小伙伴也不会很多,它默认的 1h 估计很多耗时连接也不可能去做这么长时间的操作。

keepalive_timeout

设置客户端的长连接在服务器端保持的最长时间

keepalive_timeout timeout [header_timeout];

在 timeout 设置的时间内,客户端未发起新请求,则长连接关闭。第二个参数为可选项,设置 “Keep-Alive: timeout=time” 响应头的值,可以为这两个参数设置不同的值。“Keep-Alive: timeout=time” 响应头可以被 Mozilla 和 Konqueror 浏览器识别和处理,MSIE 浏览器在大约 60 秒后会关闭长连接。

默认安装完成之后的 Nignx 配置中,这个选项被设置为 65 。如果发现 Nginx 占用服务器的 CPU 特别高,可以尝试调低这个时间,或者直接设置成 0 ,设置成 0 后将整个关闭 keepalive 长连接的功能。

现在我们一起来进行测试,首先添加如下配置。

http {
  ……
  keepalive_timeout  0;
 ……
}

重载配置后使用一个 Linux 命令查看连接情况。

[root@localhost html]# netstat -nat|grep -i "80"
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN

看来目前还没有连接过来,我们可以访问之前的 /testkeepalive1.html ,马上就能看到有新的连接建立了。

[root@localhost html]# netstat -nat|grep -i "80"
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN
tcp        0      0 192.168.56.88:80        192.168.56.1:49816      TIME_WAIT
tcp        0      0 192.168.56.88:80        192.168.56.1:49811      TIME_WAIT
tcp        0      0 192.168.56.88:80        192.168.56.1:49810      TIME_WAIT
tcp        0      0 192.168.56.88:80        192.168.56.1:49814      TIME_WAIT
tcp        0      0 192.168.56.88:80        192.168.56.1:49805      TIME_WAIT
tcp        0      0 192.168.56.88:80        192.168.56.1:49812      TIME_WAIT
tcp        0      0 192.168.56.88:80        192.168.56.1:49813      TIME_WAIT

因为我们将 keepalive_timeout 设置成 0 了,所以现在有 7 条连接建立成功,注意,我使用的是 Chrome ,所以还会自带一个 /favicon.ico 请求,加上前面的 html 以及 5 个 js ,正好 7 个连接。如果速度快点过来查看的话,可以看到连接是 ESTABLISHED 状态,表示连接正在使用,TIME_WAIT 表示连接在等待中。

接下来,我们修改 keepalive_timeout 为 5 ,意思就是 5 秒,如果没有使用,就会用新的连接。现在再次访问,会看到依然建立了 5 个连接,毕竟我们相当于同时请求本地的虚拟机,速度还是够快的,只有两个连接被复用了,其它的还是建立了连接。另外,默认 Chrome 可以同时建立 6 个连接,你可以测试再多加几个 js ,然后试试,最多它就只能建立 6 个连接,前面的 js 没有加载完,后面的就会等待加载,这里和长连接无关,即使不使用长连接,也会在 6 个连接中的某一个连接释放之后才会建立新的连接。

[root@localhost html]# netstat -nat|grep -i "80"
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN
tcp        0      0 192.168.56.88:80        192.168.56.1:52469      ESTABLISHED
tcp        0      0 192.168.56.88:80        192.168.56.1:52471      ESTABLISHED
tcp        0      0 192.168.56.88:80        192.168.56.1:52470      ESTABLISHED
tcp        0      0 192.168.56.88:80        192.168.56.1:52472      ESTABLISHED
tcp        0      0 192.168.56.88:80        192.168.56.1:52465      ESTABLISHED

在 5 秒内,刷新页面,不会有新的连接出现,但是等待 5 秒后,再次刷新,就会发现又有新的连接建立了。

[root@localhost html]# netstat -nat|grep -i "80"
tcp        0      0 0.0.0.0:8080            0.0.0.0:*               LISTEN
tcp        0      0 0.0.0.0:80              0.0.0.0:*               LISTEN
tcp        0      0 192.168.56.88:80        192.168.56.1:52469      TIME_WAIT
tcp        0      0 192.168.56.88:80        192.168.56.1:52471      TIME_WAIT
tcp        0      0 192.168.56.88:80        192.168.56.1:52692      ESTABLISHED
tcp        0      0 192.168.56.88:80        192.168.56.1:52691      ESTABLISHED
tcp        0      0 192.168.56.88:80        192.168.56.1:52690      ESTABLISHED
tcp        0      0 192.168.56.88:80        192.168.56.1:52686      ESTABLISHED
tcp        0      0 192.168.56.88:80        192.168.56.1:52693      ESTABLISHED
tcp        0      0 192.168.56.88:80        192.168.56.1:52470      TIME_WAIT
tcp        0      0 192.168.56.88:80        192.168.56.1:52472      TIME_WAIT
tcp        0      0 192.168.56.88:80        192.168.56.1:52465      TIME_WAIT

再等待一段时间后,所有连接全部关闭。这里关闭连接的时间是操作系统决定的,与操作系统被动断开 TCP 连接的配置有关,主要是 net.ipv4.tcp_tw_reuse 这个配置,大家可以自己查阅相关的资料。正常情况下是在 TIME_WAIT 状态后等待大约 2 分钟,最低可以修改为 1 分钟,通过下面的命令。这个是操作系统的固定值,最低只能是 60 秒,也就是这个 1 分钟。

[root@localhost html]# sysctl net.ipv4.tcp_tw_reuse=1
[root@localhost html]# sysctl -p

这样一分钟以后这些连接信息就会消失了。设置成 0 不管用的,一样会等待,客户端关掉浏览器也没用。这个命令真实的作用其实是如果连接是安全可控的,可以复用 TIME_WAIT 的连接为新的连接所用。它可以快速复用处于 TIME_WAIT 状态的 TCP 连接,也就相当于缩短 TIME_WAIT 状态的持续时间。只有客户端主动关闭连接才会让服务器的正常关闭,使用 curl 命令测试就可以看到效果,你不会看到任何等待的连接。

关于 TIME_WAIT ,其实是为了能够正确、自然地进行 TCP 四次挥手而预留的等待时间,更具体的内容,大家可以再自行查阅 WSL(最大报文生产周期) 相关的知识点。同时,net.ipv4.tcp_tw_reuse 也要慎用,当客户端与服务端主机时间不同步时,客户端的发送的消息有可能会被直接拒绝掉。正式环境使用时,建议:别动!保持默认就好。

长连接总结

关于长连接的内容写了这么多,但其实也仅仅只是四个配置指令而已。更重要的其实是对于 HTTP 基础知识的学习,长连接现在在 Nginx 中是默认打开的,这几个选项也都是有默认值配置好的。所以平常其实我们不太需要去关心他们的配置。就像上面说的,如果发现 CPU 莫名升高,而且是因为 Nginx 的话,那么可以适当调节部分参数。但 CPU 的问题也不一定仅仅是连接的问题,gzip 同样也会带来 CPU 的压力。因此,调优是一个综合的活,要找到问题所在才好应对,比如我们还可以查看连接中 TIME_WAIT 的情况来看是不是连接非常多,这时更好的方案其实是要做负载均衡分散压力了。

连接处理

连接处理主要是针对 Nginx 如何来关闭客户端连接的一些配置操作。Nginx 在接收客户端的请求时可能由于客户端或服务端出错了,要立即响应错误信息给客户端,而 Nginx 在响应错误信息后大分部情况下是需要关闭当前连接的。Nginx 执行完 write() 系统调用(操作系统函数,参考网络编程或操作系统相关资料)把错误信息发送给客户端,write() 系统调用返回成功并不表示数据已经发送到客户端,有可能还在 tcp 连接的 write buffer 里。所以当在某些场景下出现 tcp write buffer 里的数据在 write() 系统调用之后到 close() 系统调用执行之前没有发送完毕,且 tcp read buffer 里面还有数据没有读,close() 系统调用会导致客户端收到 RST 报文且不会拿到服务端发送过来的错误信息数据。

所以,解决问题的重点是,让服务端别发 RST 包。或者说延迟发送,这就是下面要讲的 lingering_close 所要解决的问题。

上面的概念看着就很晕吧,如何测试我也没找到相关的资料,自己也尝试了半天没有什么效果。所以对这一块有了解的同学可以评论区留言哦。在实际应用中,是否应该打开 lingering_close 呢?这个就没有固定的推荐值了,lingering_close 的主要作用是保持更好的客户端兼容性,但是却需要消耗更多的额外资源(比如连接会一直占着)。因此,秉承对于不懂的东西,默认的就是最好的原则,咱们保持默认状态就好了。将来如果学习或者接触到这一块的内容了,再写文章和录视频进行详细的学习吧。

lingering_close

控制 Nginx 如何关闭客户端连接。

lingering_close off | on | always;

它的默认值是 on ,指示 Nginx 在完成关闭连接前等待和处理客户端发来的额外数据。但只有在预测客户端可能发送更多数据的情况才会做此处理。为了控制关闭HTTP/2连接,必须在 server 下(1.19.1)指定该指令。

  • always 指示 Nginx 无条件等待和处理客户端的额外数据。

  • off 指示nginx立即关闭连接,而绝不等待客户端传送额外数据。 这样做破坏了协议,所以正常条件下不应使用。

lingering_time

lingering_close 生效时(非off),这条指令定义 Nginx 处理(读取但忽略)客户端额外数据的最长时间。

lingering_time time;

默认值是 30s,超过这段时间后,Nginx 将关闭连接,不论是否还有更多数据待处理。

lingering_timeout

lingering_close 生效时(非off),这条指令定义 Nginx 等待客户端更多数据到来的最长时间。

lingering_timeout time;

默认值是 5s ,如果在这段时间内,Nginx 没有接收到数据,Nginx 将关闭连接。否则,Nginx 将接收数据,忽略它,然后再等待更多数据。 这个“等待——接收——忽略”的循环一直重复,但总时间不会超过 lingering_time 指令定义的时间。

总结

怎么说呢,学这些真的想回去好好再补补网络知识了。就这么点内容,也已经是边查资料边测试边写了,后面还有那么多配置以及牵涉到的相关知识,想想都头大。不过没关系,谁让自己喜欢这行呢,各位同学是不是也感觉到每次看完文章或者视频也会跟我一样多少会有一点点的进步呢?

长连接一般我们都会简单配置一下,通常也是以 keepalive_time 和 keepalive_time_out 的配置为主,其它两个说实话,没学之前我都不知道有这俩货。另外一个连接处理相关的配置更是从来没用过。但是,现在起码我们了个印象,将来或许哪天它们就能为我们解决大问题呢。

参考文档:

http://nginx.org/en/docs/http/ngx_http_core_module.html文章来源地址https://www.toymoban.com/news/detail-579020.html

到了这里,关于【Nginx08】Nginx学习:HTTP核心模块(五)长连接与连接处理的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【Nginx04】Nginx学习:HTTP核心模块(一)简单搭建

    前面就说过了,HTTP 模块是整个 Nginx 中最核心的模块。在这其中,它又有一部分最核心的模块,其实也就是在编译安装的时候,我们不装任何扩展就自带的模块。这一部分模块就像是基本的 PHP 语法一样,是最基础的,也是我们最需要重点掌握的内容。 今天先入个门,搭起简

    2024年02月12日
    浏览(56)
  • 【Nginx15】Nginx学习:HTTP核心模块(十二)内嵌变量

    关于内嵌变量,其实就是 Nginx 开放给我们的在配置文件中可以使用的变量。源码中无非就是替换成真实的代码变量进行操作。这些变量可以帮助我们做很多事情。之前的文章中其实也有不少地方用到了,比如说  $uri  这个变量,是不是已经见过很多次了。而且这些变量基本

    2024年02月14日
    浏览(42)
  • 【Nginx13】Nginx学习:HTTP核心模块(十)Types、AIO及其它配置

    今天学习的内容也比较简单,主要的是 Types 相关的配置,另外还会了解一下 AIO 以及部分没有特别大的分类归属的配置指令的使用。后面的内容都是 HTTP 核心模块中比较小或者比较简单的部分了。有很多配置项其实我们平常并不常用,甚至很多在学习之前我都不知道有它们的

    2024年02月12日
    浏览(51)
  • 【Nginx12】Nginx学习:HTTP核心模块(九)浏览器缓存与try_files

    浏览器缓存在 Nginx 的 HTTP 核心模块中其实只有两个简单的配置,这一块也是 HTTP 的基础知识。之前我们就一直在强调,学习 Nginx 需要的就是各种网络相关的基础知识,其中更重要的就是 HTTP 和 TCP 相关的内容。另外一个 try_files 配置指令也是 Nginx 中非常常用的一个指令,用于

    2024年02月15日
    浏览(38)
  • nginx http模块

    location的定义包含以下几种 =:表示精确匹配,只有请求的url路径与后面的字符串完全相等时,才会命中,不支持location嵌套 ~:表示使用正则定义的,区分大小写 ~*:表示是使用正则定义的,不区分大小写 ^~:表示该符号后面的字符是最佳匹配,采用该规则,不再进行后续的查

    2023年04月08日
    浏览(39)
  • Nginx安装http2和ssl模块

    Nginx在执行默认安装命令的时候,并不会编译启用ngx_http_v2_module模块。故在修改Nginx配置文件启用http2.0协议的时候会报错。 一.检查Nginx安装了哪些模块 如图就是没有安装ngx_http_v2_module模块 二.重新编译Nginx Nginx有两个目录,一个是安装目录,一个是源码目录,安装目录就是执

    2024年01月16日
    浏览(42)
  • Nginx ngx_http_auth_request_module模块鉴权

    ngx_http_auth_request_module 模块 实现了基于一子请求的结果的客户端的授权。如果子请求返回2xx响应码,则允许访问。如果它返回401或403,则访问被拒绝并显示相应的错误代码。子请求返回的任何其他响应代码都被认为是错误的。 auth_request 使用的也是 subrequest 进行子请求。 当我

    2024年02月17日
    浏览(58)
  • 使用nginx实现自定义大小预览缩略图,http_image_filter模块的安装使用

    本预览图功能使用的是nginx的http_image_filter模块,可以自定义缓存大小解决占用服务器容量问题,建议配合fastDFS使用 http_image_filter不会改变图片原始比例 例如原始图片尺寸为16:9,那么输入宽高值之后会以较小的一个参数展现预览图,比如原始图为1600*900,传递参数320*90会拿到

    2023年04月24日
    浏览(38)
  • 万字长文!一次性弄懂 Nginx 处理 HTTP 请求的 11 个阶段

    本文涉及到的所有配置文件我已经放在了 Nginx 配置文件,大家可以自取。 前面给大家讲了 Nginx 是如何处理 HTTP请求头部的,接下来就到了真正处理 HTTP 请求的阶段了。先看下面这张图,这张图是 Nginx 处理 HTTP 请求的示意图,虽然简单,但是却很好的说明了整个过程。 Read

    2024年04月16日
    浏览(49)
  • 【Nginx22】Nginx学习:FastCGI模块(四)错误处理及其它

    FastCGI 最后一篇,我们将学习完剩下的所有配置指令。在这里,错误处理还是单独拿出来成为一个小节了,而剩下的内容都放到其它中进行学习。不要感觉是其它的就没用了,有些配置指令还是非常重要的哦,或许正好你现在的项目就能用上呢。 今天学习的内容都是可以设置

    2024年02月10日
    浏览(36)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包