注意此参数过大可能遭遇到Syn flood攻击 , 即对方发送多个Syn报文端填充满Syn队列 , 使server无法继续接受其他连接
可参考此文http://tech.uc.cn/?p=1790
我们看下 man 手册上是如何说的:
The behavior of the backlog argument on TCP sockets changed with Linux 2.2. Now it specifies the queue length for com‐ pletely established sockets waiting to be accepted, instead of the number of incomplete connection requests. The maximum length of the queue for incomplete sockets can be set using /proc/sys/net/ipv4/tcp_max_syn_backlog. When syncookies are enabled there is no logical maximum length and this setting is ignored. See tcp(7) for more information. If the backlog argument is greater than the value in /proc/sys/net/core/somaxconn, then it is silently truncated to that value; the default value in this file is 128. In kernels before 2.4.25, this limit was a hard coded value, SOMAXCONN, with the value 128.
自 Linux 内核 2.2 版本以后 , backlog 为已完成连接队列的最大值 , 未完成连接队列大小以 /proc/sys/net/ipv4/tcp_max_syn_backlog 确定 , 但是已连接队列大小受 SOMAXCONN 限制 , 为 min(backlog, SOMAXCONN)
3.net.ipv4.tcp_syncookies
修改此参数可以有效的防范上面所说的syn flood攻击
原理:在Tcp服务器收到Tcp Syn包并返回Tcp Syn+ack包时 , 不专门分配一个数据区 , 而是根据这个Syn包计算出一个cookie值 。在收到Tcp ack包时 , Tcp服务器在根据那个cookie值检查这个Tcp ack包的合法性 。如果合法 , 再分配专门的数据区进行处理未来的TCP连接 。
默认为0 , 1表示开启
4.net.ipv4.tcp_keepalive_time
Tcp keepalive心跳包机制 , 用于检测连接是否已断开 , 我们可以修改默认时间来间断心跳包发送的频率 。
keepalive一般是服务器对客户端进行发送查看客户端是否在线 , 因为服务器为客户端分配一定的资源 , 但是Tcp 的keepalive机制很有争议 , 因为它们可耗费一定的带宽 。
Tcp keepalive详情见Tcp/ip详解卷1 第23章
5.net.ipv4.tcp_tw_reuse
我的上一篇文章中写到了time_wait状态 , 大量处于time_wait状态是很浪费资源的 , 它们占用server的描述符等 。
修改此参数 , 允许重用处于time_wait的socket 。
默认为0 , 1表示开启
6.net.ipv4.tcp_tw_recycle
也是针对time_wait状态的 , 该参数表示快速回收处于time_wait的socket 。
默认为0 , 1表示开启
7.net.ipv4.tcp_fin_timeout
修改time_wait状的存在时间 , 默认的2MSL
注意:time_wait存在且生存时间为2MSL是有原因的 , 见我上一篇博客为什么会有time_wait状态的存在 , 所以修改它有一定的风险 , 还是根据具体的情况来分析 。
8.net.ipv4.tcp_max_tw_buckets
所允许存在time_wait状态的最大数值 , 超过则立刻被清楚并且警告 。
9.net.ipv4.ip_local_port_range
表示对外连接的端口范围 。
10.somaxconn
前面说了Syn队列的最大长度限制 , somaxconn参数决定Accept队列长度 , 在listen函数调用时backlog参数即决定Accept队列的长度 , 该参数太小也会限制最大并发连接数 , 因为同一时间完成3次握手的连接数量太小 , server处理连接速度也就越慢 。服务器端调用accept函数实际上就是从已连接Accept队列中取走完成三次握手的连接 。
Accept队列和Syn队列是listen函数完成创建维护的 。
/proc/sys/net/core/somaxconn修改
上面每一个参数其实都够写一篇文章来分析了 , 这里我只是概述下部分参数 , 注意在修改Tcp参数时我们一定要根据自己的实际需求以及测试结果来决定 。
问题描述
场景:JAVA的client和server , 使用socket通信 。server使用NIO 。
1.间歇性得出现client向server建立连接三次握手已经完成 , 但server的selector没有响应到这连接 。
2.出问题的时间点 , 会同时有很多连接出现这个问题 。
3.selector没有销毁重建 , 一直用的都是一个 。
4.程序刚启动的时候必会出现一些 , 之后会间歇性出现 。
分析问题
正常TCP建连接三次握手过程:
第一步:client 发送 syn 到server 发起握手;
第二步:server 收到 syn后回复syn+ack给client;
第三步:client 收到syn+ack后 , 回复server一个ack表示收到了server的syn+ack(此时client的56911端口的连接已经是established) 。
推荐阅读
- 为什么水龙头的水突然小了,自来水出水量大小和水龙头有关吗
- 一个排风扇一天用多少电 排风扇耗电量大不大
- 千万级 高并发“秒杀”架构设计
- 淘宝店铺怎么提高流量和销量 淘宝新店如何提高销量
- 汽车排量大小的区别
- 空气能热水器耗电量大吗,空气能热水器要长期通电吗
- 阿里架构师教你处理高并发:2种方法,解决Redis和Mysql一致性
- 梦见被交警开罚单周公解梦 梦见被交警开罚单并发生争执
- 高并发之API接口,分布式,防刷限流,如何做?
- 如何模拟超过 5 万用户的并发访问?
