正在跑一个 puma 进程,主要是根据业务进行 302 跳转
puma 我使用的是 workers 的方式 使用常规配置 workers threads 2,16
本身跑的速度还行,newrelic 的数据 action 响应在 10ms 以内,rpm 4k 上下
但是发现机器里大概几千个 TIME_WAIT , 感觉这跟 established 差的也太远了吧
67 ESTABLISHED
7 LISTEN
2187 TIME_WAIT
跟着网上说的调整了下内核参数,稍微调整了下,发现没有什么变化
net.ipv4.tcp_tw_reuse=1
net.ipv4.tcp_fin_timeout=30
# 内核不支持修改 tcp_tw_recycle
回头看 nginx 日志里的 request_time,好像也都比较正常
查了下资料 发现其实我这个量还比较小,端口号够用就行
那么到底我是否该关注这个指标呢?
如果需要关注,那么如何解决这个问题呢?
主要都是 puma 端口上的 TIME_WAIT
tcp 0 0 172.16.0.13:3001 172.16.0.13:58594 TIME_WAIT
tcp 0 0 172.16.0.13:3001 172.16.0.13:34790 TIME_WAIT
tcp 0 0 172.16.0.13:3001 172.16.0.13:57166 TIME_WAIT
tcp 0 0 172.16.0.13:3001 172.16.0.13:34378 TIME_WAIT
tcp 0 0 172.16.0.13:46242 172.16.0.12:3000 TIME_WAIT
tcp 0 0 172.16.0.13:3001 172.16.0.13:60220 TIME_WAIT
tcp 0 0 172.16.0.13:3001 172.16.0.13:32940 TIME_WAIT
tcp 0 0 172.16.0.13:3001 172.16.0.13:59416 TIME_WAIT
tcp 0 0 172.16.0.13:3001 172.16.0.13:57810 TIME_WAIT
tcp 0 0 172.16.0.13:3001 172.16.0.13:35356 TIME_WAIT
tcp 0 0 172.16.0.13:33226 172.16.0.13:3001 TIME_WAIT
tcp 0 0 172.16.0.13:443 223.104.94.24:53306 TIME_WAIT
tcp 0 0 172.16.0.13:3001 172.16.0.13:35066 TIME_WAIT
tcp 0 0 172.16.0.13:3001 172.16.0.13:58744 TIME_WAIT
tcp 0 0 172.16.0.13:46138 172.16.0.12:3000 TIME_WAIT
tcp 0 0 172.16.0.13:3001 172.16.0.13:60702 TIME_WAIT
tcp 0 0 172.16.0.13:3001 172.16.0.13:35518 TIME_WAIT
tcp 0 0 172.16.0.13:3001 172.16.0.13:60944 TIME_WAIT
tcp 0 0 172.16.0.13:3001 172.16.0.13:57132 TIME_WAIT
tcp 0 0 172.16.0.13:3001 172.16.0.13:60464 TIME_WAIT
tcp 0 0 172.16.0.13:47050 172.16.0.12:3000 TIME_WAIT
tcp 0 0 172.16.0.13:443 117.136.63.83:14588 TIME_WAIT
tcp 0 0 172.16.0.13:50070 172.16.0.12:3000 TIME_WAIT
tcp 0 0 172.16.0.13:3001 172.16.0.13:34458 TIME_WAIT
tcp 0 0 172.16.0.13:3001 172.16.0.13:33596 TIME_WAIT
tcp 0 0 172.16.0.13:3001 172.16.0.13:35192 TIME_WAIT
tcp 0 0 172.16.0.13:3001 172.16.0.13:60730 TIME_WAIT
tcp 0 0 172.16.0.13:3001 172.16.0.13:59854 TIME_WAIT
tcp 0 0 172.16.0.13:3001 172.16.0.13:59854 TIME_WAIT
看这个 TIME_WAIT 是 nginx 和 puma 之间的连接,试试设置 nginx upstream keepalive 应该能解决这个问题。
upstream api_production {
server 172.16.0.13:3001 fail_timeout=0;
server 172.16.0.12:3001 fail_timeout=0;
keepalive 500;
}
server {
listen 80;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "Upgrade";
proxy_set_header X-Forwarded-Proto http;
listen 443 ssl;
ssl_certificate /root/.acme.sh/fullchain.cer;
ssl_certificate_key /root/.acme.sh/key;
add_header Strict-Transport-Security "max-age=31536000";
root /var/www/api/current/public;
try_files $uri/index.html $uri;
location /api {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $host;
proxy_redirect off;
proxy_pass http://api_production;
}
location / {
rewrite ^/(.*)$ /api/$1 last;
proxy_pass http://api_production;
}
你在 location 里面添加这 2 个试试看,具体说明请参考 nginx 的文档:
proxy_http_version 1.1;
proxy_set_header Connection "";
两千多个挺正常的,你 nginx 和 puma 是跑在同一台机器上的,nginx 每次转发请求实际上都会创建新的 TCP 连接,连接没有被复用后面就 timewait 了。如果并发量高的话确实会出问题,upstream 就会连不上,sourceIP:Port -> DesIp:Port 耗尽了。
一般有几个解决方案:
有两台机器实际上,A 和 B 都有 Puma, A 有 nginx
A 的 nginx 的 upstream 分别到 A 和 B 的 PUMA 上
我也觉得 2000 多还好,
local_port 不改也有 2w-3w, 目前肯定是够用
主要还是怂
因为这个项目的业务逻辑关系,流量特别不稳定,经常瞬发 10x 平日流量,我怕到瓶颈再想办法就比较麻烦了
其实我觉得开一下 tcp_tw_reuse 应该问题不是太大,就算占满了都有解
总之 感谢 @early @quakewang