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 的配置:
- http配置段的 keepalive_timeout 项
- http配置段的 keepalive_request 项
- upstream 代码段的 keepalive 项
2. keepalive 介绍
什么是 keepalive?作用是什么?
keepalive 是在 TCP 中一个可以检测死连接的机制,作用是保持 socket 长连接不被断开,属于 TCP 层的功能,并不属于应用层。
TCP 层怎么做到保持长连接的?
Linxu 中有三个参数,开发给应用层使用:

net.ipv4.tcp_keepalive_intvl = 探测间隔,未收到回复时,重试的时间间隔,单位:秒
net.ipv4.tcp_keepalive_probes = 探测次数,重试次数
net.ipv4.tcp_keepalive_time = 探测的心跳间隔,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 主动断开连接。
Nginx - keepliave 相关知识点的更多相关文章
- UITableView相关知识点
//*****UITableView相关知识点*****// 1 #import "ViewController.h" // step1 要实现UITableViewDataSou ...
- Android开发涉及有点概念&相关知识点(待写)
前言,承接之前的 IOS开发涉及有点概念&相关知识点,这次归纳的是Android开发相关,好废话不说了.. 先声明下,Android开发涉及概念比IOS杂很多,可能有很多都题不到的.. 首先由 ...
- IOS开发涉及有点概念&相关知识点
前言,IOS是基于UNIX的,用C/C+/OC直通系统底层,不想android有个jvm. 首先还是系统架构的分层架构 1.核心操作系统层 Core OS,就是内存管理.文件系统.电源管理等 2.核心 ...
- IOS之UI--小实例项目--添加商品和商品名(使用xib文件终结版) + xib相关知识点总结
添加商品和商品名小项目(使用xib文件终结版) 小贴士:博文末尾有项目源码在百度云备份的下载链接. xib相关知识点总结 01-基本使用 一开始使用xib的时候,如果要使用自定义view的代码,就需要 ...
- 学习记录013-NFS相关知识点
一.NFS相关知识点 1.NFS常用的路径/etc/exports NFS服务主配置文件,配置NFS具体共享服务的地点/usr/sbin/exportfs NFS服务的管理命令,exportfs -a ...
- TCP/IP 相关知识点与面试题集
第一部分:TCP/IP相关知识点 对TCP/IP的整体认 链路层知识点 IP层知识点 运输层知识点 应用层知识点 (这些知识点都可以参考:http://www.cnblogs.com/newwy/p/ ...
- nginx几个知识点汇总
WHY? 为什么用Nginx而不用LVS? 7点理由足以说明一切:1 .高并发连接: 官方测试能够支撑 5 万并发连接,在实际生产环境中跑到 2 - 3 万并发连接数.?2 .内存消耗少: 在 3 万 ...
- Python开发一个csv比较功能相关知识点汇总及demo
Python 2.7 csv.reader(csvfile, dialect='excel', **fmtparams)的一个坑:csvfile被csv.reader生成的iterator,在遍历每二 ...
- Caffe学习系列(二)Caffe代码结构梳理,及相关知识点归纳
前言: 通过检索论文.书籍.博客,继续学习Caffe,千里之行始于足下,继续努力.将自己学到的一些东西记录下来,方便日后的整理. 正文: 1.代码结构梳理 在终端下运行如下命令,可以查看caffe代码 ...
随机推荐
- 洛谷 P1053 逛公园 解题报告
P3953 逛公园 问题描述 策策同学特别喜欢逛公园. 公园可以看成一张\(N\)个点\(M\)条边构成的有向图,且没有自环和重边.其中1号点是公园的入口,\(N\)号点是公园的出口,每条边有一个非负 ...
- 用ladon框架封装Python为Webservice接口以及调用接口的方法
一.用ladon框架封装Python为Webservice接口 功能实现的同时,希望将接口开放给别人,而封装python接口的一个再简单不过的框架Ladon,而且提供不同的协议,包括SOAP和Json ...
- RF parameter
There are primarily 3 features which can be tuned to improve the predictive power of the model : 说明: ...
- No module named 'urllib.request'; 'urllib' is not a package
想学爬虫urllib的设置代理服务器,于是把之前跳过没学的urllib捡起来,敲了段简单的代码,如下 import urllib.request url = "http://www.baid ...
- P1077 摆花
P1077 摆花 题目描述 小明的花店新开张,为了吸引顾客,他想在花店的门口摆上一排花,共 m 盆.通过调查顾客的喜好,小明列出了顾客最喜欢的 n 种花,从 1 到 n 标号.为了在门口展出更多种花, ...
- python反射,单例模式
# getattr# hasattr# setattr# delattr class Foo: def __init__(self, name,age): self.name = name self. ...
- SQL统计每科前三名的学生的语句
偶然在论坛看到一个网友的帖子,关于他遇到一个面试题的,网站写了很多,我看了一下,结果应该是没问题的,但是为何面试官还是不满意,我想面试官可能并不是想考你真能把这道题做出来,而是看你如何简洁的通过一个s ...
- python学习笔记3-函数的递归
递归就是指自己函数的自我调用 #递归 #自己调用自己,函数的循环 def test1(): num = int(input('please enter a number:')) if num%2==0 ...
- node.js 基础篇
日志输出方式 node test.js 2>error.log 1>info.log 如果需要日志文件追加 node test.js 2>>error.log 1>> ...
- 关于Java的“找不到或无法加载主类”
Java编程思想4th第六章的关于访问权限和包的笔记总结时遇到了一个关于package命名及导入的问题. 环境:Ubuntu 16.04.3 LTS x86_64 首先,我要安装部署Java的开发环境 ...