跳转至

缩短长连接

让长连接在不活跃时快速断开,以最大化释放系统资源,可以通过以下几种方式来实现:


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)可以设置超时策略,强制断开空闲连接。

方法:

  1. TCP 超时设置: 使用 conntrack 模块设置连接超时时间。
# 设置空闲连接的超时时间为 60 秒
iptables -A INPUT -p tcp --dport 8080 -m conntrack --ctstate ESTABLISHED -m timeout --idle 60 -j ACCEPT
  1. 检查当前 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

综合建议

  1. 短时间内需要快速释放资源

  2. 调整 tcp_keepalive_time 和相关参数。

  3. 配合防火墙超时规则,快速清理空闲连接。

  4. 高效、灵活控制

  5. 在应用层实现超时检测,并与客户端协议配合(如心跳、定时断开)。

  6. 测试和优化

  7. 根据业务场景调试超时时间,确保在节约资源和避免过早断开的平衡点。

这样可以更好地满足释放系统资源的需求,同时避免影响正常的业务通信。