二丫讲梵 二丫讲梵
首页
  • 最佳实践
  • 迎刃而解
  • Nginx
  • Php
  • Zabbix
  • AWS
  • Prometheus
  • Grafana
  • CentOS
  • Systemd
  • Docker
  • Rancher
  • Ansible
  • Ldap
  • Gitlab
  • GitHub
  • Etcd
  • Consul
  • RabbitMQ
  • Kafka
  • MySql
  • MongoDB
  • OpenVPN
  • KVM
  • VMware
  • Other
  • ELK
  • K8S
  • LLM
  • Nexus
  • Jenkins
  • 随写编年
  • 家人物语
  • 追忆青春
  • 父亲的朋友圈
  • 电影音乐
  • 效率工具
  • 博客相关
  • Shell
  • 前端实践
  • Vue学习笔记
  • Golang学习笔记
  • Golang编程技巧
  • 学习周刊
  • Obsidian插件周刊
关于
友链
  • 本站索引

    • 分类
    • 标签
    • 归档
  • 本站页面

    • 导航
    • 打赏
  • 我的工具

    • 备忘录清单 (opens new window)
    • json2go (opens new window)
    • gopher (opens new window)
    • 微信MD编辑 (opens new window)
    • 国内镜像 (opens new window)
    • 出口IP查询 (opens new window)
    • 代码高亮工具 (opens new window)
  • 外站页面

    • 开往 (opens new window)
    • ldapdoc (opens new window)
    • HowToStartOpenSource (opens new window)
    • vdoing-template (opens new window)
GitHub (opens new window)

二丫讲梵

行者常至,为者常成
首页
  • 最佳实践
  • 迎刃而解
  • Nginx
  • Php
  • Zabbix
  • AWS
  • Prometheus
  • Grafana
  • CentOS
  • Systemd
  • Docker
  • Rancher
  • Ansible
  • Ldap
  • Gitlab
  • GitHub
  • Etcd
  • Consul
  • RabbitMQ
  • Kafka
  • MySql
  • MongoDB
  • OpenVPN
  • KVM
  • VMware
  • Other
  • ELK
  • K8S
  • LLM
  • Nexus
  • Jenkins
  • 随写编年
  • 家人物语
  • 追忆青春
  • 父亲的朋友圈
  • 电影音乐
  • 效率工具
  • 博客相关
  • Shell
  • 前端实践
  • Vue学习笔记
  • Golang学习笔记
  • Golang编程技巧
  • 学习周刊
  • Obsidian插件周刊
关于
友链
  • 本站索引

    • 分类
    • 标签
    • 归档
  • 本站页面

    • 导航
    • 打赏
  • 我的工具

    • 备忘录清单 (opens new window)
    • json2go (opens new window)
    • gopher (opens new window)
    • 微信MD编辑 (opens new window)
    • 国内镜像 (opens new window)
    • 出口IP查询 (opens new window)
    • 代码高亮工具 (opens new window)
  • 外站页面

    • 开往 (opens new window)
    • ldapdoc (opens new window)
    • HowToStartOpenSource (opens new window)
    • vdoing-template (opens new window)
GitHub (opens new window)
  • 最佳实践

  • 迎刃而解

  • Nginx

  • Php

  • Zabbix

  • AWS

  • Prometheus

  • Grafana

  • Loki

  • CentOS

    • Linux好用命令之w命令
    • Linux好用命令之top命令
    • Linux好用命令之free命令
    • Linux好用命令之lsof命令
    • Linux好用命令之expect命令
    • Linux好用命令之gzip保留原文件解压缩
    • Linux好用命令之dig命令
    • Linux好用命令之rsync命令
    • Linux好用命令之curl劫持请求的三种方式
    • Linux好用命令之base64命令
    • Linux好用命令之figlet命令
    • Linux好用命令之watch命令
    • 使用trash-cli给Linux服务器加一个回收站的功能
    • CentOS-7中tmp目录的清理规则
    • 用yum的方式快速安装lnmp环境(MySQL5-5&5-7,php5-x&7-x)
    • CentOS系统里TCP状态中TIME_WAIT超过3万的分析与建议
      • 定义
      • 分析
      • 解决
    • CentOS-7如何释放主机根分区的磁盘空间
    • 实践一次抓包看到TCP的三次握手与四次挥手及其他
    • CentOS-arm架构下安装docker
    • Logrotate入门了解及生产实践
    • 为什么不建议Linux用root登陆或启动服务
  • Supervisord

  • Systemd

  • Docker

  • Docker-Compose

  • Rancher

  • Ansible

  • OpenLdap

  • GitLab

  • GitHub

  • Etcd

  • Consul

  • RabbitMQ

  • Kafka

  • Mysql

  • MongoDB

  • OpenVPN

  • Kvm

  • VMware

  • 配置文件详解

  • Other

  • 运维观止
  • CentOS
二丫讲梵
2020-03-25
目录

CentOS系统里TCP状态中TIME_WAIT超过3万的分析与建议

文章发布较早,内容可能过时,阅读注意甄别。

通过如下命令,我们可以看到系统当中 TCP 状态中的情况:

$ netstat -n | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"\t",state[key]}'
LAST_ACK     192
SYN_RECV     97
CLOSE_WAIT   2
ESTABLISHED      14418
FIN_WAIT1    389
FIN_WAIT2    1706
SYN_SENT     2
CLOSING      51
TIME_WAIT    17697
1
2
3
4
5
6
7
8
9
10

当然了,如果我们配置了系统监控,那么从 Prometheus 中看系统 TCP 状态会更加清晰。

主机上的 TCP 状态的 TIME_WAIT 数非常高,在三万到五万之间徘徊,这是相当高的,在分析问题原因以及给出解决方案之前,先来理解一下这个 TIME_WAIT 是个什么东东。

# 定义

我们的应用对外提供服务,当 TCP 连接主动关闭时,都会经过 TIME_WAIT 状态。TCP 四次握手结束后,连接双方都不再交换消息,但主动关闭的一方会保持这个连接在一段时间内不可用。

# 分析

那么,保持这么一个状态有什么用呢?

为了理解 TIME_WAIT 状态的必要性,我们先来假设没有这么一种状态会导致的问题。暂以 A、B 来代指 TCP 连接的两端,A 为主动关闭的一端。

  • 四次挥手中,A 发 FIN, B 响应 ACK,B 再发 FIN,A 响应 ACK 实现连接的关闭。而如果 A 响应的 ACK 包丢失,B 会以为 A 没有收到自己的关闭请求,然后会重试向 A 再发 FIN 包。

此时,如果没有 TIME_WAIT 状态,A 不再保存这个连接的信息,收到一个不存在的连接的包,A 会响应 RST 包,导致 B 端异常响应。

此时, TIME_WAIT 是为了保证全双工的 TCP 连接正常终止。

我们还知道,TCP 下的 IP 层协议是无法保证包传输的先后顺序的。如果双方挥手之后,一个网络四元组(src/dst ip/port)被回收,而此时网络中还有一个迟到的数据包没有被 B 接收,A 应用程序又立刻使用了同样的四元组再创建了一个新的连接后,这个迟到的数据包才到达 B,那么这个数据包就会让 B 以为是 A 刚发过来的。

img (opens new window)

# 解决

从如上内容的分析中,我们在解决此类问题的时候,大致有两个方向可走,一个是控制一个 TCP 连接流程在系统当中的最大时间,一个是分配的 time_wait 容量池的最大容量,从这两个角度入手,一般就能比较好的控制系统当中 time_wait 的数量。

而上边说到的这两个参数,则都是在内核参数当中进行配置定义的。在 sysctl.conf 当中定义如下参数:

net.ipv4.tcp_fin_timeout = 20 # 设置单条TCP超时时间为20s,centos中默认为30s
net.ipv4.tcp_max_tw_buckets = 19400
1
2

在网上一些文章中,有建议将 net.ipv4.tcp_max_tw_buckets这个参数往大了调的,这种建议呢,或许在业务量小,没跑出系统性能的情况下,是合适的,但是如果在业务量庞大的场景下,我是不建议使劲儿把这个参数往大了调的,如果设置的过大(超过常规的 65535),那么很可能会影响正常的 TCP 请求,因此应该自行斟酌将此值设置在一个合理的范围当中。

微信 支付宝
上次更新: 2024/07/04, 22:40:37
用yum的方式快速安装lnmp环境(MySQL5-5&5-7,php5-x&7-x)
CentOS-7如何释放主机根分区的磁盘空间

← 用yum的方式快速安装lnmp环境(MySQL5-5&5-7,php5-x&7-x) CentOS-7如何释放主机根分区的磁盘空间→

最近更新
01
学习周刊-总第212期-2025年第21周
05-22
02
从赵心童世锦赛夺冠聊聊我的斯诺克情缘
05-16
03
学习周刊-总第211期-2025年第20周
05-15
更多文章>
Theme by Vdoing | Copyright © 2017-2025 | 点击查看十年之约 | 浙ICP备18057030号
  • 跟随系统
  • 浅色模式
  • 深色模式
  • 阅读模式