Nginx - keepliave 相关知识点

目录

- 1. 前言
- 2. keepalive 介绍
- 3. Nginx 与 keepalive 的关系
    - 3.1 Nginx - keepalive_timeout
    - 3.2 Nginx - keepalive_requests
    - 3.3 Nginx - upstream - keepalive

 

1. 前言

在 nginx中,有三处配置会涉及到 keepalive 的配置:

  1. http配置段的 keepalive_timeout 项
  2. http配置段的 keepalive_request 项
  3. upstream 代码段的 keepalive 项

 

2. keepalive 介绍

什么是 keepalive?作用是什么?

keepalive 是在 TCP 中一个可以检测死连接的机制,作用是保持 socket 长连接不被断开,属于 TCP 层的功能,并不属于应用层。

TCP 层怎么做到保持长连接的?

Linxu 中有三个参数,开发给应用层使用:

 

net.ipv4.tcp_keepalive_intvl = 75   探测间隔,未收到回复时,重试的时间间隔,单位:秒
net.ipv4.tcp_keepalive_probes = 9   探测次数,重试次数
net.ipv4.tcp_keepalive_time = 7200  探测的心跳间隔,TCP链接在多少秒之后没有数据报文传输启动探测报文,单位:秒

 

 

3. Nginx 与 keepalive 的关系

3.1 Nginx - keepalive_timeout

在 nginx http配置段有 keepalive_timeout 配置项,默认为 65 秒

 

keepalive_timeout 65; 服务器端主动发起keepalive连接,并保持 65 秒,如果超过65秒没有发送任何请求,则服务器主动断开连接,TCP从ESTABLISHED 转为 TIME_WAIT 状态。

 

为什么会用到 keepalive_timeout ?

通过配置 keepalive_timeout 可以实现服务器与客户端之间的长连接,用户连接访问服务器可能不止 1 次请求,使用keepalive可以减少系统对TCP连接的建立和销毁的开销。

 

接下来通过抓包来验证 开启 和 关闭 keepalive_timeout 的两种情况:

(1)测试1 - 配置 keepalive_timeout 为 0

192.168.118.15:nginx服务器
192.168.118.94:客户端

 

 

配置如下:

抓包分析:

当设置 keepalive_timeout 0 时,用户发起一个请求,创建一个TCP连接,完成请求后,nginx端主动发送 FIN 断开,从ESTABLISHED 转为 TIME_WAIT 当第二个请求再来时,重复以上步骤。

在创建和销毁TCP连接的同时,会消耗系统资源。在高并发的时候,会造成大量系统资源的浪费,产生很多 TIME_WAIT 连接占用端口,如果不能及时的断开,则会造成系统端口用尽的情况。

当设置 keepalive_timeout 0 时,通过浏览器快速刷新,查看nginx服务器连接数:

 

可以看到, 充斥着大量的 TIME_WAIT 状态的tcp连接,这只截了一部分。

(2)测试2 - 配置 keepalive_timeout 65

 

 

 首先,从时间上分析下keepalive 保活,从上图看, TCP Keep-Alive 是 10 秒中,没有任何数据传输才会触发 keepalive保活机制。

在从这张图来看,在 nginx 中,keepalive_timeout 的解释应该是:如果 65 秒中之内,没有接收到任何数据,则主动断开,如果在65秒内有数据传输,则从最后一次数据传输完毕后,重置计时时间。

从 TCP 追踪流来看

 

在 keepalive_timeout 时间内的请求, 都由一个 TCP 连接进行处理了,TCP连接得到很好的复用,减少了系统的开销。

当设置 keepalive_timeout 65 时,通过浏览器快速刷新,查看nginx服务器连接数:

可以看到, 对于一个客户端,只需要开启一个tcp连接请求就能轻松实现请求处理,大大减低了资源的浪费。

 

总结:

对于nginx来说,开启 keepalive_timeout 还是很有必要的,通过测试也得知,keepalive_timeout 是从最后一个请求开始计时,对于高并发的主机来说,这个时间可以适当的进行调整。

 

3.2 Nginx - keepalive_requests

keepalive_requests指令用于设置一个keep-alive连接上可以服务的请求的最大数量,当最大请求数量达到时,连接被关闭,值为0会也禁用keep-alive客户端连接;。默认是100。

答案显而易见,通过 keepalive_timeout keepalive_requests 来管理长连接:

  •   当一个tcp连接存活时间超过 keepalive_timeout 时则会被close掉,nginx的具体实现,是通过定时器来做的
  •   当一个tcp连接最大数超过 keepalive_requests 时则也会被close掉

 

(1)测试1 - keepalive_requests 为 0

 

抓包分析如下:

 

 当 keepalive_requests 为 0 的时候,keepalive 的关闭的状态,1个TCP连接处理1个请求。和keepalive_timeout 为 0 一样的效果。因此要开启keepalive时,这两个参数都不能为0

 

(2)测试-2 - keepalive_requests 为 3

 

抓包分析如下:

当设置 keepalive_requests 为 3 时,一个TCP 连接最多响应用户请求 3 次就强制断开连接,不会等到 keepalive_timeout 时间后断开。

 

总结:

    keepalive_requests 就等于是设置 一个 TCP 连接的处理请求的数量,当请求等于设定的这个数值,就断开该连接,如果用户再次发起连接则新建一个TCP连接响应用户。

 

3.3 Nginx - upstream - keepalive

 为了测试 upstream 中的 keepalive 的功能,后端服务器采用 tomcat

 主机信息:

客户端     192.168.118.94
nginx     192.168.118.15
tomcat    192.168.118.16

 

 在 http 1.1 中可以配置服务器端开启 keepalive 与客户端保持长连接。接下来看 nginx与后端服务器怎样交互的。

nginx 配置如下:

 

keepalive_timeout:65 设置nginx开启keepalive,超时时间为65秒,也就是说:如果客户端65秒内没有后续的请求过来,nginx就会断掉这个TCP连接,设置为0表示禁用keepalive。
keepalive_requests :100 设置长连接能够处理请求的次数,100表示:一个长连接nginx最多处理100次请求就会关闭。

这两个配置项,上面已经得到了证实。

keepalive : 10 这个值必须设置,默认为0. 设置每个worker可以保持长连接空闲时的最大连接数。

这里需要特别解释一下,假设nginx有100个请求需要访问Tomcat,那么会建立100个连接,如果双方都支持keepalive,那么这100个连接都是长连接(可以复用那种的),当请求结束后,nginx会立马销毁 90个(100-90),只剩下10个长连接,这10个长连接在Tomcat的keepAliveTimeout时间到期后由Tomcat方关闭。

Tomcat的 keepAliveTimeout这个值可以设置大一些,性能会很好,比如设置个10分钟,20分钟的。

 

测试

用户端用浏览器快速的刷新,首先查看 nginx 连接情况:

可以看到火狐浏览器启动了 5 个tcp连接来加载资源,无论怎么刷新,连接都不会变化,这就是因为使用了 keepalive,所有的连接可以进行复用,如果把 nginx 的keepalive_timeout 设置为 0 ,每次刷新都会使用新的 TCP 连接,这里会出现大量的 TIME_WAIT 的连接。

接下来,查看 tomcat 服务器连接情况:

 

只截图了一部分,出现了大量的 TIME_WAIT 的 tcp 连接,也就是说 客户端与 nginx 连接时确实是用了keepalive,但是nginx与tomcat的连接却没有启用keepalive,每一次请求都新建一个 tcp,用完一次就关闭没有复用,所以出现了大量的TIME_WAIT的TCP连接,如果流量稍微大一些tomcat服务器会因为tcp资源耗尽而宕机。

通过上面的配置,在 upstream 中,已经配置过 keepalive,为什么没有生效呢?

这里就需要抓包分析 nginx 与 tomcat 之间是不是依然采用的http1.0 短连接通信:

 

客户端连接nginx时,使用的 http1.1,并设置了 keepalive 头

 

而 nginx 请求tomcat时,采用的是 http1.0,并且 connection 设置了 close 告诉 tomcat 连接只用一次,用完关闭。

 

通过上面分析,很明确的知道了 nginx 到 tomcat 采用的是 http1.0 短连接模式。查看官方:

 

 

需要在 location 中配置:

proxy_http_version 1.1;
proxy_set_header Connection "";

 

现在 nginx 到后端的连接也是 http1.1

 

接下来,还是通过浏览器刷新,查看服务器连接状态:

nginx 服务器查看如下:

 

 一共 10 个连接, 其中 5 个是 客户端与 nginx 的连接,另外 5 个是nginx与tomcat的连接。

再次查看 tomcat 服务器连接状态:

 

tomcat 上一共是 5 个与 nginx 服务器的连接。这样 nginx 与 tomcat 也是 keepalive 长连接了。

这里在补充下,经过测试,nginx 与 后端 tomcat 断开是由 tomcat 中 connectionTimeout 决定的,而且是由后端tomcat 主动断开连接。

 

本文作者:hukey

本文链接:https://www.cnblogs.com/hukey/p/10506556.html

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   hukey  阅读(4183)  评论(2编辑  收藏  举报
历史上的今天:
2016-03-10 [ 手记 ] Oracle 11g安装过程
点击右上角即可分享
微信分享提示
💬
评论
📌
收藏
💗
关注
👍
推荐
🚀
回顶
收起
  1. 1 彩虹 Jay
彩虹 - Jay
00:00 / 00:00
An audio error has occurred.

彩虹 + 轨迹 (Live) - 周杰伦 (Jay Chou)

彩虹

词:周杰伦

曲:周杰伦

哪里有彩虹告诉我

哪里有彩虹告诉我

能不能把我的愿望还给我

能不能把我的愿望还给我

为什么天这么安静

为什么天这么安静

所有的云都跑到我这里

有没有口罩一个给我

有没有口罩一个给我

释怀说了太多就成真不了

释怀说了太多就成真不了

也许时间是一种解药

也许时间是一种解药

也是我现在正服下的毒药

也是我现在正服下的毒药

看不见你的笑 我怎么睡得着

看不见你的笑 我怎么睡得着

你的声音这么近我却抱不到

你的声音这么近我却抱不到

没有地球太阳还是会绕

没有地球太阳还是会绕

没有理由我也能自己走

没有理由我也能自己走

你要离开 我知道很简单

你要离开 我知道很简单

你说依赖 是我们的阻碍

你说依赖 是我们的阻碍

就算放开 但能不能别没收我的爱

就算放开 但能不能别没收我的爱

当作我最后才明白

当作我最后才明白

看不见你的笑 要我怎么睡得着

看不见你的笑 要我怎么睡得着

你的声音这么近我却抱不到

没有地球太阳还是会绕 会绕

没有理由我也能自己走掉

释怀说了太多就成真不了

也许时间是一种解药 解药

也是我现在正服下的毒药

轨迹

词:黄俊郎

曲:周杰伦

我会发着呆然后忘记你

接着紧紧闭上眼

想着哪一天 会有人代替

想着哪一天 会有人代替

让我不再想念你

我会发着呆 然后微微笑

我会发着呆 然后微微笑

接着紧紧闭上眼

又想了一遍 你温柔的脸

又想了一遍 你温柔的脸

在我忘记之前