nginx的keepalive和keepalive_requests(性能测试TPS波动)
当使用nginx作为反向代理时,为了支持长连接,需要做到两点:
- 从client到nginx的连接是长连接
- 从nginx到server的连接是长连接
保持和client的长连接:
http {
keepalive_timeout 120s 120s;
keepalive_requests 10000;
}
keepalive_timeout
#语法
keepalive_timeout timeout [header_timeout];
- 第一个参数:设置keep-alive客户端(浏览器)连接在服务器端(nginx端)保持开启的超时值(默认75s);值为0会禁用keep-alive客户端连接;
- 第二个参数:可选、在响应的header域中设置一个值“Keep-Alive: timeout=time”;通常可以不用设置;
这个keepalive_timeout针对的是浏览器和nginx建立的一个tcp通道,没有数据传输时最长等待该时候后就关闭.
nginx和upstream中的keepalive_timeout则受到tomcat连接器的控制,tomcat中也有一个类似的keepalive_timeout参数
keepalive_requests
keepalive_requests指令用于设置一个keep-alive连接上可以服务的请求的最大数量,当最大请求数量达到时,连接被关闭。默认是100。
这个参数的真实含义,是指一个keep alive建立之后,nginx就会为这个连接设置一个计数器,记录这个keep alive的长连接上已经接收并处理的客户端请求的数量。如果达到这个参数设置的最大值时,则nginx会强行关闭这个长连接,逼迫客户端不得不重新建立新的长连接。
保持和server的长连接
为了让nginx和后端server(nginx称为upstream)之间保持长连接,典型设置如下:(默认nginx访问后端都是用的短连接(HTTP1.0),一个请求来了,Nginx 新开一个端口和后端建立连接,后端执行完毕后主动关闭该链接)
http {
upstream BACKEND {
server 192.168.0.1:8080 weight=1 max_fails=2 fail_timeout=30s;
server 192.168.0.2:8080 weight=1 max_fails=2 fail_timeout=30s;
keepalive 300; // 这个很重要!
}
server {
listen 8080 default_server;
server_name "";
location / {
proxy_pass http://BACKEND;
proxy_set_header Host $Host;
proxy_set_header x-forwarded-for $remote_addr;
proxy_set_header X-Real-IP $remote_addr;
add_header Cache-Control no-store;
add_header Pragma no-cache;
proxy_http_version 1.1; // 这两个最好也设置
proxy_set_header Connection "Keep-Alive";
}
}
}
HTTP协议中对长连接的支持是从1.1版本之后才有的,因此最好通过proxy_http_version指令设置为”1.1”;
从client过来的http header,因为即使是client和nginx之间是短连接,nginx和upstream之间也是可以开启长连接的。
keepalive
此处keepalive的含义不是开启、关闭长连接的开关;也不是用来设置超时的timeout;更不是设置长连接池最大连接数。官方解释:
- The connections parameter sets the maximum number of idle keepalive connections to upstream servers connections(设置到upstream服务器的空闲keepalive连接的最大数量)
- When this number is exceeded, the least recently used connections are closed. (当这个数量被突破时,最近使用最少的连接将被关闭)
- It should be particularly noted that the keepalive directive does
not limit the total number of connections to upstream servers that an nginx worker process can open.(特别提醒:keepalive指令不会限制一个nginx worker进程到upstream服务器连接的总数量)
我们先假设一个场景: 有一个HTTP服务,作为upstream服务器接收请求,响应时间为100毫秒。如果要达到10000 QPS的性能,就需要在nginx和upstream服务器之间建立大约1000条HTTP连接。nginx为此建立连接池,然后请求过来时为每个请求分配一个连接,请求结束时回收连接放入连接池中,连接的状态也就更改为idle。我们再假设这个upstream服务器的keepalive参数设置比较小,比如常见的10.
A、假设请求和响应是均匀而平稳的,那么这1000条连接应该都是一放回连接池就立即被后续请求申请使用,线程池中的idle线程会非常的少,趋进于零,不会造成连接数量反复震荡。
B、显示中请求和响应不可能平稳,我们以10毫秒为一个单位,来看连接的情况(注意场景是1000个线程+100毫秒响应时间,每秒有10000个请求完成),我们假设应答始终都是平稳的,只是请求不平稳,第一个10毫秒只有50,第二个10毫秒有150:
- 下一个10毫秒,有100个连接结束请求回收连接到连接池,但是假设此时请求不均匀10毫秒内没有预计的100个请求进来,而是只有50个请求。注意此时连接池回收了100个连接又分配出去50个连接,因此连接池内有50个空闲连接。
- 然后注意看keepalive=10的设置,这意味着连接池中最多容许保留有10个空闲连接。因此nginx不得不将这50个空闲连接中的40个关闭,只留下10个。
- 再下一个10个毫秒,有150个请求进来,有100个请求结束任务释放连接。150 - 100 = 50,空缺了50个连接,减掉前面连接池保留的10个空闲连接,nginx不得不新建40个新连接来满足要求。
同样,如果假设相应不均衡也会出现上面的连接数波动情况。
造成连接数量反复震荡的一个推手,就是这个keepalive 这个最大空闲连接数。毕竟连接池中的1000个连接在频繁利用时,出现短时间内多余10个空闲连接的概率实在太高。因此为了避免出现上面的连接震荡,必须考虑加大这个参数,比如上面的场景如果将keepalive设置为100或者200,就可以非常有效的缓冲请求和应答不均匀。
总结:
keepalive 这个参数一定要小心设置,尤其对于QPS比较高的场景,推荐先做一下估算,根据QPS和平均响应时间大体能计算出需要的长连接的数量。比如前面10000 QPS和100毫秒响应时间就可以推算出需要的长连接数量大概是1000. 然后将keepalive设置为这个长连接数量的10%到30%。比较懒的同学,可以直接设置为keepalive=1000之类的,一般都OK的了。
综上,出现大量TIME_WAIT的情况
导致 nginx端出现大量TIME_WAIT的情况有两种:
- keepalive_requests设置比较小,高并发下超过此值后nginx会强制关闭和客户端保持的keepalive长连接;(主动关闭连接后导致nginx出现TIME_WAIT)
- keepalive设置的比较小(空闲数太小),导致高并发下nginx会频繁出现连接数震荡(超过该值会关闭连接),不停的关闭、开启和后端server保持的keepalive长连接;
导致后端server端出现大量TIME_WAIT的情况:
- nginx没有打开和后端的长连接,即:没有设置
proxy_http_version 1.1;和proxy_set_header Connection "Keep-Alive";从而导致后端server每次关闭连接,高并发下就会出现server端出现大量TIME_WAIT
nginx的keepalive和keepalive_requests(性能测试TPS波动)的更多相关文章
- 性能测试学习之三—— PV->TPS转换模型&TPS波动模型
PV->TPS转换模型 由上一篇“性能测试学习之二 ——性能测试模型(PV计算模型)“ 得知 TPS = ( (80%*总PV)/(24*60*60*(T/24)))/服务器数量 转换需要注意: ...
- Nginx Upstream Keepalive 分析 保持长连接
Nginx Upstream长连接由upstream模式下的keepalive指令控制,并指定可用于长连接的连接数,配置样例如下: upstream http_backend { server ...
- nginx之keepalive
一:设置 keepalive_timeout 0; 发curl: [xxx ~]$ curl -H "Keep-Alive: 60" -H "Connection: k ...
- 服务端性能测试 TPS
针对服务器端的性能,以TPS为主来衡量系统的性能,并发用户数为辅来衡量系统的性能,如果必须要用并发用户数来衡量的话,需要一个前提,那就是交易在多长时间内完成,因为在系统负载不高的情况下,将思考时间( ...
- Nginx http keepalive针对客户端行为指令
keepalive 描述 多个http请求可以复用Tcp链接 减少握手次数 通过减少并发连接数减少服务器资源消耗 降低Tcp拥塞控制影响 Syntax: keepalive_disable none ...
- 关于 Nginx upstream keepalive 的说明
模块是 HttpUpstreamModule,配置的一个例子: [shell]upstream http_backend { server 127.0.0.1:8080; keepalive 1 ...
- 性能测试TPS目标值确定-二八原则
在性能测试中通常使用二八原则来量化业务需求. 二八原则:指80%的业务量在20%的时间里完成. TPS(QPS)=并发数/响应时间 例:如某个公司1000个员工,在周五下午3点-5点有90%的员工登陆 ...
- 记一次线上由nginx upstream keepalive与http协议"协作"引起的接口报错率飙高事件
年前接到个任务,说要解决线上一些手机客户端接口报错率很高的问题.拿到了监控邮件,粗略一看,各种50%+的错误率,简直触目惊心.这种疑难杂症解决起来还是挺好玩的,于是撸起袖子action. 最终的结果虽 ...
- 性能测试 tps持续走低,响应时间持续增加,瓶颈分析
吞吐量图如上 响应时间图如上 自身压测的机器,资源使用率并没有饱和 服务器,top命令下看到load average的值很低,本身是4核的server. 每个核的CPU使用率也极低,空闲cpu占95+ ...
- Nginx09 http的keepalive及在nginx的配置使用
1 为什么要有Connection: keep-alive? 在早期的HTTP/1.0中,每次http请求都要创建一个连接,而创建连接的过程需要消耗资源和时间,为了减少资源消耗,缩短响应时间,就需要重 ...
随机推荐
- DASCTF 2023 & 0X401七月暑期挑战赛
比赛只出了一道,小菜不是罪过-_- controlflow 这个题动调到底就行 for i in range(40): after_xor[i]=inp[i]^0x401 after_xor[i] + ...
- 对JavaScript中与字符串相关的方法总结
JavaScript中的字符串是由16位码元code unit组成.通常来说,一个字符=16位码元,该类字符也叫做单码元字符.还有一种字符组成策略是代理对,它由两对16位码元组成,即一个字符对应两个1 ...
- 树链剖分 | 洛谷 P4114 Qtree1
前言 题目链接:洛谷 P4114 Qtree1 前置知识:树链剖分 题意 给定一棵树,有修改边权和查询两点之间边权最大值两种操作,对于每个查询输出结果. 解析 已经在前置博客里提到,树链剖分 可以将树 ...
- [编程基础] Python内置模块collections使用笔记
collections是Python标准库中的一个内置模块,它提供了一些额外的数据结构类型,用于增强Python基础类型如列表(list).元组(tuple)和字典(dict)等.以下是对collec ...
- ipmitool配置机器的BMC
一.设置IP地址 1.确定操作对象 #ipmitool mc info 输出中"Device Revision"是命令的操作对象 2.设置BMC IP # ipmitool -I ...
- redhat7 team bonding 双网卡绑定 主备 负载均衡
team简介 team也被称为网络组,是将多个网卡聚合在一起,从而实现冗错和提高吞吐量.适用于redhat7.0以上版本,至多可支持8块网卡.team相对于之前的bonding技术,能提供更好的性能和 ...
- 在 Net7.0环境下测试了 Assembly.Load、Assmebly.LoadFile和Assembly.LoadFrom的区别
一.简介 很长时间没有关注一些C#技术细节了,主要在研究微服务.容器.云原生.编批等高大上的主题了,最近在写一些框架的时候,遇到了一些和在 Net Framework 框架下不一样的情况,当然了,我今 ...
- 「atcoder - abc246h」01? Queries
link. 平时基本打不到 ex,这个 ex 还是比较 ez 的,但也有些需要注意的地方. 考虑 dp 规划前缀,设 \(f[i][0/1]\) 表示前缀 \([1, i]\) 否是选 \(i\) 的 ...
- 「Tricks」整体DP
不太了解这个东西的具体定义是什么,总之应该是一个用数据结构维护 DP 状态的某几个维度的 trick 吧. 事实上你可以把这篇 post 理解为三个题的解集. 先直接来看 noi2020 - Dest ...
- Solution -「洛谷 P5610」「YunoOI 2013」大学
Description Link. 区间查 \(x\) 的倍数并除掉,区间查和. Solution 平衡树. 首先有个基本的想法就是按 \(a_{i}\) 开平衡树,即对于每个 \(a_{i}\) 都 ...