没有合适的资源?快使用搜索试试~ 我知道了~
首页tcp短连接TIME_WAIT问题解决方法
资源详情
资源评论
资源推荐

tcp 短连接 TIME_WAIT 问题解决方法
(1)——短连接
tcp 连接是网络编程中最基础的概念,基于不同的使用场景,我们一般区分为“长连接”
和“短连接”,
长短连接的优点和缺点这里就不详细展开了,有心的同学直接去 google 查询,本文主
要关注如何解决 tcp 短连接的 TIME_WAIT 问题。
短连接最大的优点是方便,特别是脚本语言,由于执行完毕后脚本语言的进程就结束
了,基本上都是用短连接。
但短连接最大的缺点是将占用大量的系统资源,例如:本地端口、socket 句柄。
导致这个问题的原因其实很简单:tcp 协议层并没有长短连接的概念,因此不管长连接还
是短连接,连接建立->数据传输->连接关闭的流程和处理都是一样的。
正常的 TCP 客户端连接在关闭后,会进入一个 TIME_WAIT 的状态,持续的时间一般在
1~4 分钟,对于连接数不高的场景,1~4 分钟其实并不长,对系统也不会有什么影响,
但如果短时间内(例如 1s 内)进行大量的短连接,则可能出现这样一种情况:客户端所
在的操作系统的 socket 端口和句柄被用尽,系统无法再发起新的连接!
举例来说:假设每秒建立了 1000 个短连接(Web 场景下是很常见的,例如每个请求都
去访问 memcached),假设 TIME_WAIT 的时间是 1 分钟,则 1 分钟内需要建立 6W
个短连接,

由于 TIME_WAIT 时间是 1 分钟,这些短连接 1 分钟内都处于 TIME_WAIT 状态,都不
会释放,而 Linux 默认的本地端口范围配置是:net.ipv4.ip_local_port_range =
32768 61000
不到 3W,因此这种情况下新的请求由于没有本地端口就不能建立了。
可以通过如下方式来解决这个问题:
1)可以改为长连接,但代价较大,长连接太多会导致服务器性能问题,而且 PHP 等脚
本语言,需要通过 proxy 之类的软件才能实现长连接;
2)修改 ipv4.ip_local_port_range,增大可用端口范围,但只能缓解问题,不能根本解
决问题;
3)客户端程序中设置 socket 的 SO_LINGER 选项;
4)客户端机器打开 tcp_tw_recycle 和 tcp_timestamps 选项;
5)客户端机器打开 tcp_tw_reuse 和 tcp_timestamps 选项;
6)客户端机器设置 tcp_max_tw_buckets 为一个很小的值;
在解决 php 连接 Memcached 的短连接问题过程中,我们主要验证了 3)4)5)6)几
种方法,采取的是基本功能验证和代码验证,并没有进行性能压力测试验证,
因此实际应用的时候需要注意观察业务运行情况,发现丢包、断连、无法连接等现象
时,需要关注是否是因为这些选项导致的。
虽然这几种方法都可以通过 google 查询到相关信息,但这些信息大部分都是泛泛而
谈,而且绝大部分都是人云亦云,没有很大参考价值。
我们在定位和处理这些问题过程中,遇到一些疑惑和困难,也花费了一些时间去定位和
解决,以下就是相关的经验总结。

(2)——SO_LINGER
SO_LINGER 是一个 socket 选项,通过 setsockopt API 进行设置,使用起来比较简
单,但其实现机制比较复杂,且字面意思上比较难理解。
解释最清楚的当属《Unix 网络编程卷 1》中的说明(7.5 章节),这里简单摘录:
SO_LINGER 的值用如下数据结构表示:
struct linger {
int l_onoff; /* 0 = off, nozero = on */
int l_linger; /* linger time */
};
其取值和处理如下:
1、设置 l_onoff 为 0,则该选项关闭,l_linger 的值被忽略,等于内核缺省情况,close
调用会立即返回给调用者,如果可能将会传输任何未发送的数据;
2、设置 l_onoff 为非 0,l_linger 为 0,则套接口关闭时 TCP 夭折连接,TCP 将丢弃保
留在套接口发送缓冲区中的任何数据并发送一个 RST 给对方,
而不是通常的四分组终止序列,这避免了 TIME_WAIT 状态;
3、设置 l_onoff 为非 0,l_linger 为非 0,当套接口关闭时内核将拖延一段时间(由
l_linger 决定)。
如果套接口缓冲区中仍残留数据,进程将处于睡眠状态,直 到(a)所有数据发送完
且被对方确认,之后进行正常的终止序列(描述字访问计数为 0)
剩余13页未读,继续阅读



















安全验证
文档复制为VIP权益,开通VIP直接复制

评论0