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代码 ...
随机推荐
- debian8安装harbor
这里的系统版本是debian8.8,harbor版本为1.1.2. 1.安装docker-ce 1.1.Install packages to allow apt to use a repositor ...
- Mysql的概述
Mysql的概述 Mysql的安装和初次使用 Mysql的基本概念 Mysql的英文单词是: database,简称 DB. 什么是数据库? 用于存储和管理数据的仓库 数据库的特点: 持久化存储数据. ...
- GDB调试工具
1.运行代码的三种情况 a.运行时有逻辑问题 gdb a.out 设置断点 单行执行 b.运行代码没有退出 一直运行 结束不了 挂载调试 跟踪调试 -g ...
- 【Asp.net入门16】第一个ASP.NET 应用程序-总结
本章创建了一个新的ASP.NET项目,并用它创建了一个简单的数据输入应用程序,向你初步介绍 了ASP.NET平台.本章省略了许多重要的功能,只为向你说明ASP.NET应用程序所执行的核心操作—— 使用 ...
- P2831 愤怒的小鸟
P2831 愤怒的小鸟 从 \((0, 0)\) 发射一只鸟, 轨迹满足抛物线, 问最少几只鸟可以打完 \(n <= 18\) 只猪 错误日志: 处理抛物线数组没有初始化 Solution 数据 ...
- c# string 和 byte[]数组之间转换
在文件流读取和存储过程当中,经常涉及到byte[]数组形式存储数据,再此过程中也涉及到String类型字符串和byte[]的类型转换,下面我们举例说明一下. 现在有一个字符串: string str ...
- Spring Cloud微服务实战阅读笔记(一) 基础知识
本文系<Spring Cloud微服务实战>作者:翟永超,一书的阅读笔记. 一:基础知识 1:什么是微服务架构 是一种架构设计风格,主旨是将一个原本独立的系统拆分成多个小型服务 ...
- logstash定义表达式
例如: echo '[2018/02/02 08:34:43.032]' >> tomcat_catalina.out 过滤方式 "message" => &qu ...
- call 大佬 三分姿势
为什么注释掉的三分方式不能过 @大佬 题目来源:http://hihocoder.com/problemset/problem/1142?sid=1003381 貌似不是eps的问题 #include ...
- noi题库(noi.openjudge.cn) 1.13编程基础之综合应用 T12 分数求和
12:分数求和 描述 输入n个分数并对他们求和,并用最简形式表示.所谓最简形式是指:分子分母的最大公约数为1:若最终结果的分母为1,则直接用整数表示. 如:5/6.10/3均是最简形式,而3/6需要化 ...