You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

如何解决大量HTTP请求引发的CLOSE_WAIT连接堆积问题?

如何解决大量HTTP请求引发的CLOSE_WAIT连接堆积问题?

嗨,碰到CLOSE_WAIT堆积这种问题确实挺闹心的,尤其是你这儿上千个Python脚本同时跑,每个都在打8088端口的请求。先给你理清楚:CLOSE_WAIT状态本质是客户端这边没主动关闭TCP连接——服务器已经发了关闭请求(FIN包),但客户端进程还没调用close()释放连接,导致连接一直挂在那儿。结合你的场景,咱们从几个层面来解决:

一、优化Python Requests的连接使用方式

你的脚本里直接用requests.get(),默认情况下requests会用urllib3的连接池,但如果每个脚本跑完就退出,或者没正确处理响应,连接就容易留在CLOSE_WAIT状态。试试这几个调整:

1. 使用Session对象复用连接

单个脚本里用requests.Session()代替直接调用requests.get(),Session会自动复用TCP连接,减少频繁创建/关闭连接的次数,从根源减少CLOSE_WAIT的产生。修改你的脚本示例:

import socket
import requests

def get_yarn_details(state='RUNNING'):
    state_suffix = '' if state == '' else "?states=" + state
    yarn_apps = "http://{0}:8088/ws/v1/cluster/apps" + state_suffix
    local_fqdn = socket.getfqdn(socket.gethostname())
    yarn_apps_url = yarn_apps.format(local_fqdn)

    # 使用Session复用连接
    with requests.Session() as session:
        try:
            with session.get(yarn_apps_url) as response:
                response.raise_for_status()
                apps = response.json().get('apps', {}).get('app', [])
                for app in apps:
                    print(app['id'])
        except requests.exceptions.RequestException as e:
            print(f"Error fetching YARN details: {e}")

# Example usage
get_yarn_details()

这里用了两层with:Session的with会自动关闭会话,get的with会自动关闭响应连接,确保连接被正确释放。

2. 显式设置连接超时

给请求加上超时时间,避免请求卡住导致连接长期占用:

# 在get请求里加timeout参数,比如5秒超时
with session.get(yarn_apps_url, timeout=5) as response:

二、减少脚本的并发数量

你现在是上千个独立脚本在跑,每个脚本启动后创建新的进程,每个进程的连接池是独立的,根本没法复用连接,反而会产生大量一次性连接。试试这些优化:

  • 批量请求合并:把多个脚本的逻辑整合到一个脚本里,用多线程/多进程批量处理请求,而不是每个请求启动一个独立脚本。
  • 改用定时任务调度:比如用cron或者Celery来集中调度请求,减少同时运行的进程数,让连接池能真正发挥复用作用。

三、调整RHEL系统的TCP参数

如果上面的应用层优化还不够,咱们从系统层面加快CLOSE_WAIT连接的回收:

1. 缩短CLOSE_WAIT的超时时间

默认情况下,Linux的tcp_fin_timeout是60秒,也就是CLOSE_WAIT状态的连接会保留60秒才回收。咱们把它调小,比如15秒:

# 临时生效
sysctl -w net.ipv4.tcp_fin_timeout=15

# 永久生效,写入/etc/sysctl.conf文件
echo "net.ipv4.tcp_fin_timeout=15" >> /etc/sysctl.conf
sysctl -p

2. 开启连接复用参数

开启tcp_tw_reusetcp_tw_recycle(注意:如果你的机器在NAT网络环境下,tcp_tw_recycle可能会导致连接异常,谨慎开启):

# 临时生效
sysctl -w net.ipv4.tcp_tw_reuse=1
sysctl -w net.ipv4.tcp_tw_recycle=1

# 永久生效
echo "net.ipv4.tcp_tw_reuse=1" >> /etc/sysctl.conf
echo "net.ipv4.tcp_tw_recycle=1" >> /etc/sysctl.conf
sysctl -p

3. 调整最大TIME_WAIT连接数

如果连接堆积严重,可以适当增大tcp_max_tw_buckets的值,避免系统因为连接数过多拒绝新请求:

sysctl -w net.ipv4.tcp_max_tw_buckets=65536
echo "net.ipv4.tcp_max_tw_buckets=65536" >> /etc/sysctl.conf
sysctl -p

四、检查YARN ResourceManager的配置

偶尔也可能是服务器端的问题:比如RM的HTTP服务设置了过短的连接超时,主动关闭了连接,但客户端没及时响应。可以检查RM的yarn.resourcemanager.webapp.address相关配置,看看是否有异常的超时设置,或者是否有连接泄漏的情况。

先从应用层的优化入手(用Session、合并脚本),这是最根本的解决办法,系统参数调优作为辅助。按这个步骤来,应该能大幅减少CLOSE_WAIT的数量。

备注:内容来源于stack exchange,提问作者jessica

火山引擎 最新活动