Linux 下的 TCP参数优化(详解)
简介
TCP是一种面向广域网的通信协议,目的是在跨越多个网络通信时,为两个通信端点之间提供一条具有下列特点的通信方式
(1)基于流的方式;
(2)面向连接;
(3)可靠通信方式;
(4)在网络状况不佳的时候尽量降低系统由于重传带来的带宽开销;
(5)通信连接维护是面向通信的两个端点的,而不考虑中间网段和节点。
为满足TCP协议的这些特点,TCP协议做了如下的规定
1. 数据分片:在发送端对用户数据进行分片,在接收端进行重组,由TCP确定分片的大小并控制分片和重组;
2. 到达确认:接收端接收到分片数据时,根据分片数据序号向发送端发送一个确认;
3. 超时重发:发送方在发送分片时启动超时定时器,如果在定时器超时之后没有收到相应的确认,重发分片;
4. 滑动窗口:TCP连接每一方的接收缓冲空间大小都固定,接收端只允许另一端发送接收端缓冲区所能接纳的数据,TCP在滑动窗口的基础上提供流量控制,防止较快主机致使较慢主机的缓冲区溢出;
5. 失序处理:作为IP数据报来传输的TCP分片到达时可能会失序,TCP将对收到的数据进行重新排序,将收到的数据以正确的顺序交给应用层;
6. 重复处理:作为IP数据报来传输的TCP分片会发生重复,TCP的接收端必须丢弃重复的数据;
7. 数据校验:TCP将保持它首部和数据的检验和,这是一个端到端的检验和,目的是检测数据在传输过程中的任何变化。如果收到分片的检验和有差错,TCP将丢弃这个分片,并不确认收到此报文段导致对端超时并重发。
以上概念摘自百度百科
不是很熟悉的或者看到概念头疼的估计已经不想看下去了
所以,我来讲点实际的东西
上图详细描述了TCP的三次握手和四次挥手
这图画的不错吧,,,所以不是我画的,下面的相关参数陈述和优化各位可以参照这个图,人家画的很不错我自己就不献丑了,,绝对不是懒得关系
下述是具体的TCP参数的优化方案
请根据实际情况进行优化!!!
#表示socket监听的backlog(当一个请求(request)尚未被处理或建立时,进入backlog)上限
#限制了接收新 TCP 连接侦听队列的大小。对于一个经常处理新连接的高负载 web服务环境来说,默认的 128 太小了。大多数环境这个值建议增加到 1024 或者更多。 服务进程会自己限制侦听队列的大小(例如 sendmail(8) 或者 Apache),常常在它们的配置文件中有设置队列大小的选项。大的侦听队列对防止拒绝服务 DoS ***也会有所帮助。
net.core.somaxconn = 262144
#表示开启重用。允许将TIME-WAIT sockets重新用于新的TCP连接,默认为0,表示关闭
net.ipv4.tcp_tw_reuse = 1
#表示开启TCP连接中TIME-WAIT sockets的快速回收,默认为0,表示关闭
net.ipv4.tcp_tw_recycle = 0
#keepalive的保持时间
net.ipv4.tcp_keepalive_time = 900
#表示如果套接字由本端要求关闭,这个参数决定了它保持在FIN-WAIT-2状态的时间(可改为30,一般来说FIN-WAIT-2的连接也极少)
net.ipv4.tcp_fin_timeout = 15
#用于向外连接的端口范围
net.ipv4.ip_local_port_range = 10000 65500
#预留端口避免占用,不同的端口可以逗号隔开
net.ipv4.ip_local_reserved_ports = 50010,10050,32275
#表示那些尚未收到客户端确认信息的连接(SYN消息)队列的长度,默认为1024,加大队列长度为819200,可以容纳更多等待连接的网络连接数。
net.ipv4.tcp_max_syn_backlog = 819200
#TIME_WAIT 状态数量
#表示系统同时保持TIME_WAIT套接字的最大数量,如果超过这个数字,TIME_WAIT套接字将立刻被清除并打印告警信息。默认为180000,更改为8192000.对于Apache,Nginx等服务器,上几行参数可以很好的减少TIME_WAIT套接字数量,但是对于Squid,效果不大。此项参数可以控制TIME_WAIT套接字的最大数量,避免Squid服务器被大量的TIME_WAIT套接字拖死
net.ipv4.tcp_max_tw_buckets = 8192000
#该参数用于设定系统中最多允许存在多少tcp套接字不被关联到任何一个用户文件句柄上。如果超过这个数字,没有与用户文件句柄关联的tcp套接字符将立即被复位,同时给出警告信息。这个限制只是为了防止简单的DoS工具。一般在系统内存比较充足的情况下,可以增大这个参数的赋值:
net.ipv4.tcp_max_orphans = 3276800
#CONNTRACK_MAX 允许的最大跟踪连接条目,是在内核内存中netfilter可以同时处理的“任务”(连接跟踪条目)
net.netfilter.nf_conntrack_max = 250000
#tcp_synack_retries 显示或设定 Linux 核心在回应 SYN 要求时会尝试多少次重新发送初始 SYN,ACK 封包后才决定放弃。这是所谓的三段交握 (threeway handshake) 的第二个步骤。即是说系统会尝试多少次去建立由远端启始的 TCP 连线。tcp_synack_retries 的值必须为正整数,并不能超过 255。因为每一次重新发送封包都会耗费约 30 至 40 秒去等待才决定尝试下一次重新发送或决定放弃。tcp_synack_retries 的缺省值为 5,即每一个连线要在约 180 秒 (3 分钟) 后才确定逾时.
net.ipv4.tcp_synack_retries = 2
#对于一个新建连接,内核要发送多少个 SYN 连接请求才决定放弃。不应该大于255,默认值是5,对应于180秒左右时间。(对于大负载而物理通信良好的网络而言,这个值偏高,可修改为2.这个值仅仅是针对对外的连接,对进来的连接,是由tcp_retries1 决定的)
net.ipv4.tcp_syn_retries = 2 #四种TCP状态的超时时间 net.netfilter.nf_conntrack_tcp_timeout_time_wait = 30 net.netfilter.nf_conntrack_tcp_timeout_fin_wait = 30 net.netfilter.nf_conntrack_tcp_timeout_close_wait = 15 net.netfilter.nf_conntrack_tcp_timeout_established = 86400
#当探测没有确认时,重新发送探测的频度。缺省是75秒。
net.ipv4.tcp_keepalive_intvl = 15
#在认定连接失效之前,发送多少个TCP的keepalive探测包。缺省值是9。这个值乘以tcp_keepalive_intvl之后决定了,一个连接发送了keepalive之后可以有多少时间没有回应
net.ipv4.tcp_keepalive_probes = 5
#本端试图关闭TCP连接之前重试多少次。缺省值是7,相当于50秒~16分钟(取决于RTO)。如果你的机器是一个重载的WEB服务器,你应该考虑减低这个值,因为这样的套接字会消耗很多重要的资源。参见tcp_max_orphans.
net.ipv4.tcp_orphan_retries = 0
#支持更大的TCP窗口. 如果TCP窗口最大超过65535(64K), 必须设置该数值为1
net.ipv4.tcp_window_scaling = 1
#当 tcp 建立连接的 3 路握手完成后,将连接置入 ESTABLISHED 状态并交付给应用程序的 backlog 队列时,会检查 backlog 队列是否已满。若已满,通常行为是将连接还原至 SYN_ACK 状态,以造成 3 路握手最后的 ACK 包意外丢失假象 —— 这样在客户端等待超时后可重发 ACK —— 以再次尝试进入 ESTABLISHED 状态 —— 作为一种修复/重试机制。如果启用 tcp_abort_on_overflow 则在检查到 backlog 队列已满时,直接发 RST 包给客户端终止此连接 —— 此时客户端程序会收到 104 Connection reset by peer 错误。
net.ipv4.tcp_abort_on_overflow = 1
#管理TCP的选择性应答,允许接收端向发送端传递关于字节流中丢失的序列号,减少了
段丢失时需要重传的段数目,当段丢失频繁时,sack是很有益的。
net.ipv4.tcp_sack = 1
#关闭tcp的连接传输的慢启动,即先休止一段时间,再初始化拥塞窗口。
net.ipv4.tcp_slow_start_after_idle = 0
#每个网络接口接收数据包的速率比内核处理这些包的速率快时,允许送到队列的数据包的最大数目
net.core.netdev_max_backlog = 300000
#内核分配给TCP连接的内存,单位是Page,1 Page = 4096 Bytes,可用命令查看:
#getconf PAGESIZE
#第一个数字表示,当 tcp 使用的 page 少于 1048576 时,kernel 不对其进行任何的干预
#第二个数字表示,当 tcp 使用了超过 1310720 的 pages 时,kernel 会进入 “memory pressure” 压力模式
#第三个数字表示,当 tcp 使用的 pages 超过 1572864 时(相当于1.6GB内存),就会报:Out of socket memory
net.ipv4.tcp_mem = 1048576 1310720 1572864
#为每个TCP连接分配的读、写缓冲区内存大小,单位是Byte
#第一个数字表示,为TCP连接分配的最小内存
#第二个数字表示,为TCP连接分配的缺省内存
#第三个数字表示,为TCP连接分配的最大内存
#一般按照缺省值分配,下面的例子就是读写均为8KB,共16KB
#1572864*16kb=25165824kb 相当于26G内存
net.ipv4.tcp_rmem = 4096 8192 16384
#默认的TCP数据接收窗口大小(字节)。
net.core.rmem_default = 1048576
#最大的TCP数据接收窗口(字节)。
net.core.rmem_max = 15728640
#为自动调优定义每个 socket 使用的内存。
#第一个值是为 socket 的发送缓冲区分配的最少字节数。
#第二个值是默认值(该值会覆盖 wmem_default),缓冲区在系统负载不重的情况下可以增长到这个值。
#第三个值是发送缓冲区空间的最大字节数(该值会覆盖 wmem_max)。
net.ipv4.tcp_wmem = 256000 768000 4194304
#各种类型的socket默认读写缓冲器大小
net.core.wmem_default = 1048576
#各种类型的socket默认读写缓冲器最大值
net.core.wmem_max = 5242880
#panic error中自动重启,等待timeout为20秒
kernel.panic = 20
#表示系统级别的能够打开的文件句柄的数量。是对整个系统的限制,并不是针对用户的。
fs.file-max = 6553560
上述很多参数值得修改,并非是绝对要这样,各位还是要根据实际需求进行参照
思量
那这些参数如何优化呢?我怎么知道如何修改比较合理呢
我的建议是,基础优化之后,进行监控,查看tcp的资源消耗和具体卡在哪里
下面是一些Linux系统下面TCP监控的大概获取方式,仅供参考
查看当前的连接数:
代码如下:
grep ip_conntrack /proc/slabinfo ip_conntrack 38358 64324 304 13 1 : tunables 54 27 8 : slabdata 4948 4948 216
获取TCP各个握手挥手的实际当前数值
代码如下:
# netstat -an | awk '/^tcp/ {++state[$6]} END {for (key in state) print key,"\t",state[key]}' TIME_WAIT 1832 CLOSE_WAIT 360 FIN_WAIT2 12 ESTABLISHED 3588 SYN_RECV 148 CLOSING 7 LAST_ACK 19 LISTEN 59
查出目前 ip_conntrack 的排名:
代码如下:
$ cat /proc/net/nf_conntrack | cut -d ' ' -f 10 | cut -d '=' -f 2 | sort | uniq -c | sort -nr | head -n 10
总结
还是最好根据实际情况进行参数调整,才最科学,不要盲目加大或者一刀切为上策

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
2020数据库选型攻略:专用VS多模
数据库选型越来越难,据DB-Engines数据库流行度排行榜显示,目前全球有多达359个开源和商业的数据库。 从应用类型看,有OLTP事务型数据库,有OLAP分析型数据库,还有HTAP混合型数据库。 从存储方式看,有关系型数据库和非关系型数据库(NoSQL)之分。而NoSQL数据库又依据支持的数据模型不同,分为键值数据库、文档数据库,列式数据库,图形数据库等。 如果从架构类型看,又分Share Everything、Share Storage、Share Nothing。 数据库市场百花齐放虽然给企业带来了更多选择,但也导致选型变得更加困难。 专用 VS 多模 关于专用数据库与多模数据库之争,由来已久。其中,AWS属于专用数据库派,认为数据库就应该像汽车一样,不同的汽车解决不同的运输需求,不同数据库去解决不同场景需求,而不是通过关系数据库来一刀切。 因此,AWS提供的数据库产品组合多达十几种。 AWS 数据库服务一览图 而甲骨文、微软、SAP则属于“瑞士军刀”派,即多模数据库派。通过扩展其SQL查询功能或添加功能(如R或Python支持)来实现多模功能。 去年,DeveloperWee...
- 下一篇
大多数企业仍在努力很大程度地利用云计算工作
根据专业服务机构埃森哲(Accenture)公司发布的一份新报告,云投资存在很多未实现的潜力。 该报告显示,大多数企业尚未意识到云投资中仍有许多尚未开发的潜力。 根据对750位高级业务和IT专业人员的调查,该报告指出,只有37%的公司设法从其投资中提取全部价值。更糟的是,在过去两年中,这一数字仅增长了2%。 超过四分之一(28%)的人完全有信心他们的云迁移计划将在分配的时间内实现期望的价值。 对于埃森哲公司而言,更轻松地将其大量迁移到云中是因为,这样做的公司将获得“明显更好的”结果。根据这份该报告,将近一半(46%)的高采用率企业完全实现了预期的收益,相比之下,中度采用率的企业为36%,低采用率的企业为28%。 对于欧洲企业而言,云计算是减轻业务不确定性和降低风险以及实现企业可持续性的好方法。但是他们仍然在寻找熟练工作人员、遵守法规以及管理旧有基础设施和应用泛滥的努力。 埃森哲公司UKI智能云基础架构负责人Emma Roscow说,“领导者很早就知道云计算是前进的方向,但是许多人行动迟缓或完全致力于其云计算战略。对于许多这样的组织来说,今年是真正的警钟,随着向远程工作的转变,它们正将潜...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- SpringBoot2编写第一个Controller,响应你的http请求并返回结果
- CentOS7编译安装Gcc9.2.0,解决mysql等软件编译问题
- CentOS8编译安装MySQL8.0.19
- CentOS8安装Docker,最新的服务器搭配容器使用
- CentOS8,CentOS7,CentOS6编译安装Redis5.0.7
- SpringBoot2整合Redis,开启缓存,提高访问速度
- Mario游戏-低调大师作品
- Docker安装Oracle12C,快速搭建Oracle学习环境
- CentOS7安装Docker,走上虚拟化容器引擎之路
- CentOS6,7,8上安装Nginx,支持https2.0的开启