`
gelongmei
  • 浏览: 219790 次
  • 性别: Icon_minigender_1
  • 来自: 深圳
文章分类
社区版块
存档分类
最新评论

cp_tw_recycle和tcp_timestamps的文章汇总

 
阅读更多
cp_tw_recycle和tcp_timestamps的文章汇总
http://blog.csdn.net/mei922/article/details/4801858TCP连接机制
http://blog.csdn.net/caianye/article/details/38540867
http://zhumeng8337797.blog.163.com/blog/static/100768914201262010163658/
2014-08-13 18:38 848人阅读 评论(0) 收藏 举报
临近年关,人会变得浮躁,期间写的代码可谓乱七八糟。不过出来混始终是要还的,这不最近就发现一个PHP脚本时常连不上服务器。

遇到这类问题,我习惯于先用strace命令跟踪了一下看看:

shell> strace php /path/to/file EADDRNOTAVAIL (Cannot assign requested address)
从字面结果看似乎是网络资源相关问题。这里顺便介绍一点小技巧:在调试的时候一般是从后往前看strace命令的结果,这样更容易找到有价值的信息。

查看一下当前的网络连接情况,结果发现TIME_WAIT数非常大:

shell> netstat -nt | awk '/^tcp/ {++state[$NF]} END {for(key in state) print key,"t",state[key]}' TIME_WAIT 28233
重复了几次测试,结果每次出问题的时候,TIME_WAIT都等于28233,这真是一个魔法数字!实际原因很简单,它取决于一个内核参数net.ipv4.ip_local_port_range:

shell> sysctl -a | grep port net.ipv4.ip_local_port_range = 32768 61000
因为端口范围是一个闭区间,所以实际可用的端口数量是:

shell> echo $((61000-32768+1)) 28233
问题分析到这里基本就清晰了,解决方向也明确了,内容所限,这里就不说如何优化程序代码了,只是从系统方面来阐述如何解决问题,无非就是以下两个方面:

首先是增加本地可用端口数量。这点可以用以下命令来实现:

shell> echo "net.ipv4.ip_local_port_range = 10240 61000" >> /etc/sysctl.conf shell> sysctl -p
其次是减少TIME_WAIT连接状态。网络上已经有不少相关的介绍,大多是建议:

shell> sysctl net.ipv4.tcp_tw_reuse=1 shell> sysctl net.ipv4.tcp_tw_recycle=1
注:通过sysctl命令修改内核参数,重启后会还原,要想持久化可以参考前面的方法。

这两个选项在降低TIME_WAIT数量方面可以说是立竿见影,不过如果你觉得问题已经完美搞定那就错了,实际上这样可能会引入一个更复杂的网络故障。

关于内核参数的详细介绍,可以参考官方文档。我们这里简要说明一下tcp_tw_recycle参数。它用来快速回收TIME_WAIT连接,不过如果在NAT环境下会引发问题。

RFC1323中有如下一段描述:

An additional mechanism could be added to the TCP, a per-hostcache of the last timestamp received from any connection.This value could then be used in the PAWS mechanism to rejectold duplicate segments from earlier incarnations of theconnection, if the timestamp clock can be guaranteed to haveticked at least once since the old connection was open. Thiswould require that the TIME-WAIT delay plus the RTT togethermust be at least one tick of the sender’s timestamp clock.Such an extension is not part of the proposal of this RFC.

大概意思是说TCP有一种行为,可以缓存每个连接最新的时间戳,后续请求中如果时间戳小于缓存的时间戳,即视为无效,相应的数据包会被丢弃。

Linux是否启用这种行为取决于tcp_timestamps和tcp_tw_recycle,因为tcp_timestamps缺省就是开启的,所以当tcp_tw_recycle被开启后,实际上这种行为就被激活了。

现在很多公司都用LVS做负载均衡,通常是前面一台LVS,后面多台后端服务器,这其实就是NAT,当请求到达LVS后,它修改地址数据后便转发给后端服务器,但不会修改时间戳数据,对于后端服务器来说,请求的源地址就是LVS的地址,加上端口会复用,所以从后端服务器的角度看,原本不同客户端的请求经过LVS的转发,就可能会被认为是同一个连接,加之不同客户端的时间可能不一致,所以就会出现时间戳错乱的现象,于是后面的数据包就被丢弃了,具体的表现通常是是客户端明明发送的SYN,但服务端就是不响应ACK,还可以通过下面命令来确认数据包不断被丢弃的现象:

shell> netstat -s | grep timestamp ... packets rejects in established connections because of timestamp
如果服务器身处NAT环境,安全起见,通常要禁止tcp_tw_recycle,至于TIME_WAIT连接过多的问题,可以通过激活tcp_tw_reuse来缓解。

进一步思考,既然必须同时激活tcp_timestamps和tcp_tw_recycle才会触发这种现象,那只要禁止tcp_timestamps,同时激活tcp_tw_recycle,就可以既避免NAT丢包问题,又降低TIME_WAIT连接数量。如果服务器并不依赖于RFC1323,那么这种方法应该也是可行的,不过最好多做测试,以防有其他的副作用。

shell> sysctl net.ipv4.tcp_timestamps=0 shell> sysctl net.ipv4.tcp_tw_recycle=1


总体来说,这次网络故障本身并没什么高深之处,本不想罗罗嗦嗦写这么多,不过拔出萝卜带出泥,在过程中牵扯的方方面面还是值得大家品味的,于是便有了这篇文字。


近来线上陆续出现了一些connect失败的问题,经过分析试验,最终确认和proc参数tcp_tw_recycle/tcp_timestamps相关;
1. 现象
第一个现象:模块A通过NAT网关访问服务S成功,而模块B通过NAT网关访问服务S经常性出现connect失败,抓包发现:服务S端已经收到了syn包,但没有回复synack;另外,模块A关闭了tcp timestamp,而模块B开启了tcp timestamp;
第二个现象:不同主机上的模块C(开启timestamp),通过NAT网关(1个出口ip)访问同一服务S,主机C1 connect成功,而主机C2 connect失败;

2. 分析
根据现象上述问题明显和tcp timestmap有关;查看linux 2.6.32内核源码,发现tcp_tw_recycle/tcp_timestamps都开启的条件下,60s内同一源ip主机的socket connect请求中的timestamp必须是递增的。
源码函数:tcp_v4_conn_request(),该函数是tcp层三次握手syn包的处理函数(服务端);
源码片段:
if (tmp_opt.saw_tstamp &&
tcp_death_row.sysctl_tw_recycle &&
(dst = inet_csk_route_req(sk, req)) != NULL &&
(peer = rt_get_peer((struct rtable *)dst)) != NULL &&
peer->v4daddr == saddr) {
if (get_seconds() < peer->tcp_ts_stamp + TCP_PAWS_MSL &&
(s32)(peer->tcp_ts - req->ts_recent) >
TCP_PAWS_WINDOW) {
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_PAWSPASSIVEREJECTED);
goto drop_and_release;
}
}
tmp_opt.saw_tstamp:该socket支持tcp_timestamp
sysctl_tw_recycle:本机系统开启tcp_tw_recycle选项
TCP_PAWS_MSL:60s,该条件判断表示该源ip的上次tcp通讯发生在60s内
TCP_PAWS_WINDOW:1,该条件判断表示该源ip的上次tcp通讯的timestamp 大于本次tcp

分析:主机client1和client2通过NAT网关(1个ip地址)访问serverN,由于timestamp时间为系统启动到当前的时间,因此,client1和client2的timestamp不相同;根据上述syn包处理源码,在tcp_tw_recycle和tcp_timestamps同时开启的条件下,timestamp大的主机访问serverN成功,而timestmap小的主机访问失败;

参数:/proc/sys/net/ipv4/tcp_timestamps - 控制timestamp选项开启/关闭
/proc/sys/net/ipv4/tcp_tw_recycle - 减少timewait socket释放的超时时间

3. 解决方法
echo 0 > /proc/sys/net/ipv4/tcp_tw_recycle;
tcp_tw_recycle默认是关闭的,有不少服务器,为了提高性能,开启了该选项;
为了解决上述问题,个人建议关闭tcp_tw_recycle选项,而不是timestamp;因为 在tcp timestamp关闭的条件下,开启tcp_tw_recycle是不起作用的;而tcp timestamp可以独立开启并起作用。
源码函数: tcp_time_wait()
源码片段:
if (tcp_death_row.sysctl_tw_recycle && tp->rx_opt.ts_recent_stamp)
recycle_ok = icsk->icsk_af_ops->remember_stamp(sk);
......

if (timeo < rto)
timeo = rto;

if (recycle_ok) {
tw->tw_timeout = rto;
} else {
tw->tw_timeout = TCP_TIMEWAIT_LEN;
if (state == TCP_TIME_WAIT)
timeo = TCP_TIMEWAIT_LEN;
}

inet_twsk_schedule(tw, &tcp_death_row, timeo,
TCP_TIMEWAIT_LEN);

timestamp和tw_recycle同时开启的条件下,timewait状态socket释放的超时时间和rto相关;否则,超时时间为TCP_TIMEWAIT_LEN,即60s;

内核说明文档 对该参数的介绍如下:
tcp_tw_recycle - BOOLEAN
Enable fast recycling TIME-WAIT sockets. Default value is 0.
It should not be changed without advice/request of technical
experts.



来源:http://blog.sina.com.cn/s/blog_781b0c850100znjd.html



在一些高并发的 WebServer上,为了端口能够快速回收,打开了net.ipv4.tcp_tw_recycle,而在关闭 net.ipv4.tcp_tw_recycle的时候,kernal 是不会检查对端机器的包的时间戳的;打开了 tcp_tw_reccycle 了,就会检查时间戳,很不幸移动的cmwap发来的包的时间戳是乱跳的,所以服务器就把带了“倒退”的时间戳的包当作是“recycle的tw连接的重传数据,不是新的请求”,于是丢掉不回包,造成大量丢包。

#ExtMail专业版# 这两天在处理一个新签客户的古怪问题,分支机构大部分用户都能访问,但少数用户时而能访问时而不行,通过缩小故障包围圈,目前初步探明是内核参数 net.ipv4.tcp_tw_recycle = 1的问题,设置为0后初步解除故障。

通过此次故障,警示我们在进行日常程序,系统等变更,修改,重启等的操作上,需要我们严格按照流程仔细去进行测试,评估修改后的风险及出现问题回退和解决方法;特别是对内核参数的修改一定要理解透彻,不能盲目修改。然后进行逐步发布,避免故障影响全局。尽量让故障率降低。
分享到:
评论

相关推荐

    tcp-tw-reuse、tcp-tw-recycle 使用场景及注意事项

    在Linux系统中,TCP/IP协议栈提供了两个参数tcp_tw_reuse和tcp_tw_recycle,用以优化TIME_WAIT状态的TCP连接处理。这些参数可以帮助系统更有效地处理网络编程中的高并发连接和负载均衡问题,同时,它们在不同的网络...

    【Linux网络编程笔记】TCP短连接产生大量TIME_WAIT导致无法对外建立新TCP连接的原因及解决方法—实践篇 - slv

    - `tcp_tw_recycle`:开启此选项可以加速TIME_WAIT连接的回收。但是,这可能导致一些兼容性问题,比如与NAT设备或防火墙的交互可能受到影响,因此在启用时需谨慎。 - `tcp_tw_reuse`:允许在协议安全的情况下复用...

    linux内核协议栈TCP time_wait原理、优化、副作用1

    快速回收功能依赖于`tcp_tw_recycle`和双方的`tcp_timestamps`。启用后,会检查报文的时间戳,不符条件的包会被丢弃,可能导致连接建立失败。在NAT环境或网络时钟不一致的情况下,这可能导致连接异常,因为同一源IP...

    Linux服务器系统性能参数配置不当引起的网站访问报错ERR-CONNECTION-TIMED-OUT 200解决方法

    进一步分析表明,问题根源在于Linux系统的TCP性能参数设置不当,特别是`tcp_tw_recycle`和`tcp_timestamps`这两个关键参数。 1. **`tcp_tw_recycle`**: - **功能**:当该参数被启用时,会启用TCP TIME_WAIT状态的...

    手机回收小程序 amouse_mobile_recycle 4.0.6.rar

    《手机回收小程序开发详解——以amouse_mobile_recycle 4.0.6为例》 在当前信息化社会,手机已经成为人们日常生活中不可或缺的一部分。随着科技的快速发展,手机更新换代的速度也在不断加快,由此产生的废旧手机...

    手机回收小程序 amouse_mobile_recycle 4.0.6.zip微信小程序模板源码

    手机回收小程序 amouse_mobile_recycle 4.0.6.zip微信小程序模板源码

    TCP TIME_WAIT常见解决方法-hanwei_1049-ChinaUnix博客1

    4. **开启tcp_tw_recycle和tcp_timestamps**: 开启这两个内核选项,可以加速TIME_WAIT状态的回收,但可能导致某些连接问题,比如穿越NAT的连接可能失败,因为TCP时间戳可能不被所有网络设备支持。 5. **启用tcp_...

    SYN报文什么时候下会被丢弃 516 - 528

    在 Linux 操作系统下,我们可以通过设置 net.ipv4.tcp_tw_reuse 和 net.ipv4.tcp_tw_recycle 两个参数来快速回收处于 TIME_WAIT 状态的连接。net.ipv4.tcp_tw_reuse 参数可以让客户端(连接发起方)在调用的 connect...

    [服务器性能优化]Linux下高并发socket最大连接数和sysctl(time_wait)设置

    为了缓解这个问题,可以调整`net.ipv4.tcp_tw_reuse`和`net.ipv4.tcp_tw_recycle`参数: ```conf net.ipv4.tcp_tw_reuse = 1 net.ipv4.tcp_tw_recycle = 1 ``` 启用`tcp_tw_reuse`允许重用TIME_WAIT套接字,而`tcp...

    解决linux下大量TIME WAIT的方法详解

    vi /etc/sysctl.conf增加以下几行: 代码如下:net.ipv4.tcp_fin_timeout = 30net.ipv4.tcp_keepalive_time = 1200net.ipv4.tcp_syncookies = 1net.ipv4.tcp_tw_reuse = 1net.ipv4.tcp_tw_recycle = 1...

    手机回收小程序amouse_mobile_recycle4.0.6.zip

    本文档是一个关于手机回收小程序的项目源码压缩包,项目名称为“amouse_mobile_recycle4.0.6”。该小程序的开发后端采用了PHP语言,前台则是以小程序的形式展现。项目源码经过了开发者严格调试,并保证可以正常运行...

    减少Linux服务器过多的TIME_WAIT

    请注意,`tcp_tw_recycle`参数在某些现代Linux内核中可能已被废弃,因为快速回收可能导致连接问题。在启用此选项前,请检查内核文档或使用较安全的其他方法。 通过上述方法,可以有效地管理和减少Linux服务器上的...

    系统调优,你所不知道的TIME_WAIT和CLOSE_WAIT1

    这也是为什么有些人会建议调整sysctl.conf中的tcp_tw_reuse和tcp_tw_recycle参数,试图复用TIME_WAIT连接或快速回收它们。 然而,直接调整这些参数并不总是最佳解决方案,因为它们可能引入其他问题,比如导致连接...

    CentOS解决服务器存在大量time_wait的问题

    7. `net.ipv4.tcp_tw_recycle`:开启TIME_WAIT连接的快速回收。 8. `net.ipv4.tcp_fin_timeout`:减少FIN-WAIT-2状态的持续时间,更快释放资源。 9. `net.ipv4.tcp_keepalive_probes`:减少超时前的探测次数,以减少...

    面试必备TCP&UDP;区别

    在Linux系统中,可以通过修改内核参数net.ipv4.tcp_tw_reuse和net.ipv4.tcp_tw_recycle为1来重用TIMEWAIT状态的连接,并快速回收TIMEWAIT状态的套接字。此外,还可以通过启用syncookies来避免在资源不足时拒绝TCP的...

    Python网络服务框架greenev.zip

    net.ipv4.tcp_tw_recycle = 1  net.ipv4.tcp_fin_timeout = 30  net.ipv4.tcp_keepalive_time = 1200  net.ipv4.ip_local_port_range = 1024 65000  net.ipv4.tcp_max_syn_backlog = 8192  fs....

    gorm golang 并发连接数据库报错的解决方法

    sysctl -w net.ipv4.tcp_tw_recycle=1 表示开启TCP连接中TIME-WAIT sockets的快速回收 以上这篇gorm golang 并发连接数据库报错的解决方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支

    irs1318_2015:2015 Recycle Rush代码

    Recycle Rush是FIRST Tech Challenge (FTC)的一个竞赛,这是一个国际性的机器人竞赛,旨在激励青少年对科学、技术、工程和数学(STEM)的兴趣。在该赛事中,参赛队伍设计、建造并编程机器人,以完成特定的挑战任务。...

    服务器大量TIME_WAIT解决方法

    * `net.ipv4.tcp_tw_recycle = 1`:表示开启 TCP 连接中 TIME-WAIT sockets 的快速回收,默认为 0,表示关闭。 * `net.ipv4.tcp_fin_timeout = 30`:修改系统默认的 TIMEOUT 时间。 2. 执行 `/sbin/sysctl -p` 命令...

Global site tag (gtag.js) - Google Analytics