缩短长连接
让长连接在不活跃时快速断开,以最大化释放系统资源,可以通过以下几种方式来实现:
1. 调整 TCP Keepalive 参数
通过调整 TCP Keepalive 的参数,可以在连接长时间不活跃时迅速检测并关闭无效连接。
配置方法:
编辑以下参数:
-
tcp_keepalive_time
:设置空闲时间(首次 keepalive 探测的等待时间)。 -
默认值是 7200 秒(2 小时),可以将其调低,例如 60 秒。
-
tcp_keepalive_intvl
:设置每次 keepalive 探测的间隔。 -
默认值是 75 秒,可以调低到 10 秒。
-
tcp_keepalive_probes
:设置最大探测次数。 -
默认值是 9 次,可以减少为 3 次。
示例:
# 临时调整
echo 60 > /proc/sys/net/ipv4/tcp_keepalive_time
echo 10 > /proc/sys/net/ipv4/tcp_keepalive_intvl
echo 3 > /proc/sys/net/ipv4/tcp_keepalive_probes
# 永久生效
cat <<EOF >> /etc/sysctl.conf
net.ipv4.tcp_keepalive_time = 60
net.ipv4.tcp_keepalive_intvl = 10
net.ipv4.tcp_keepalive_probes = 3
EOF
sysctl -p
效果:
- 空闲 60 秒后开始探测。
- 如果探测 3 次(每次间隔 10 秒)都没有响应,则关闭连接。
- 最大空闲时间为 90 秒。
2. 使用应用层超时机制
TCP Keepalive 是内核级的,但更灵活和精确的控制通常需要在应用层实现。
方法:
- 在服务器端代码中,设置一个超时时间(如 30 秒)。
- 如果连接在此时间内没有任何数据活动,主动断开连接。
示例(Python socket 超时配置):
import socket
server_socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
server_socket.settimeout(30) # 设置30秒超时时间
server_socket.bind(('0.0.0.0', 8080))
server_socket.listen(5)
while True:
try:
client_socket, addr = server_socket.accept()
print(f"Connection from {addr}")
except socket.timeout:
print("No activity, closing connection")
3. 配置防火墙规则
防火墙(如 iptables)可以设置超时策略,强制断开空闲连接。
方法:
- TCP 超时设置: 使用 conntrack 模块设置连接超时时间。
# 设置空闲连接的超时时间为 60 秒
iptables -A INPUT -p tcp --dport 8080 -m conntrack --ctstate ESTABLISHED -m timeout --idle 60 -j ACCEPT
- 检查当前 conntrack 超时设置:
cat /proc/sys/net/netfilter/nf_conntrack_tcp_timeout_established
4. 调整应用协议
如果你使用的是高层协议(如 HTTP、WebSocket),可以通过协议本身的超时机制来控制。
HTTP 连接超时设置:
- 配置服务器(如 Nginx、Apache)超时参数:
# Nginx配置
keepalive_timeout 30;
WebSocket 心跳机制:
- 定期发送心跳消息,若一段时间未收到响应,主动断开连接。
5. 系统资源限制
如果系统需要极端限制资源,可以设置最大连接数或使用 ulimit 限制文件描述符。
示例:
# 限制单个进程的最大打开文件数
ulimit -n 1024
综合建议
-
短时间内需要快速释放资源:
-
调整
tcp_keepalive_time
和相关参数。 -
配合防火墙超时规则,快速清理空闲连接。
-
高效、灵活控制:
-
在应用层实现超时检测,并与客户端协议配合(如心跳、定时断开)。
-
测试和优化:
-
根据业务场景调试超时时间,确保在节约资源和避免过早断开的平衡点。
这样可以更好地满足释放系统资源的需求,同时避免影响正常的业务通信。