You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

ThreadPoolExecutor处理7000个客户端过慢,如何优化提速?

批量API调用性能优化方案

现有代码实现

获取子客户端信息的核心函数

def get_subclient_info(client_id: int) -> list:
    subclient_url = "http://{0}/SearchSvc/CVWebService.svc/Subclient?clientId={1}".format(vault_url, client_id)
    
    subclient_info = {
            'client_id': None,
            'client_name': None,
            'subclient_id': None,
            'subclient_name': None,
            'application_id': None,
            'application_name': None,
            'instanceName': None,
            'subclient_backup_enabled': None
    }
    headers = {
        'Accept': 'application/json',
        'Content-Type': 'application/json',
        'Authtoken': '{0}'.format(access_token)
    }
    response = requests.request("GET", subclient_url, headers=headers, data=payload)
    response_json = json.loads(response.text)
    # print(response_json)
    subclient_info_list = []
    sub_clients = response_json.get('subClientProperties', {})
    for s in sub_clients:
        sub_client_data = {
            "client_id": client_id,
            "client_name": s["subClientEntity"]["clientName"],
            "subclient_id": s["subClientEntity"]["subclientId"],
            "subclient_name": s["subClientEntity"]["subclientName"],
            "application_id": s["subClientEntity"]["applicationId"],
            "application_name": s["subClientEntity"]["appName"],
            "subclient_backup_enabled": get_subclient_backup_status(s["subClientEntity"]["subclientId"]),
            "instanceName": get_subclient_InstanceName(s["subClientEntity"]["subclientId"])
        }
       
        subclient_info_list.append(sub_client_data)
    return subclient_info_list

线程池调用逻辑

import requests
import concurrent.futures

subclient_entities = {}
with concurrent.futures.ThreadPoolExecutor() as executor:
    futures_sub = [executor.submit(get_subclient_info, client_id) for client_id in list_clientid]
    for client_id, future_s in zip(list_clientid, concurrent.futures.as_completed(futures_sub)):
        result = future_s.result()
        subclient_entities[client_id] = result

当前困境

处理7000个客户端时,耗时超过1小时。先后试过普通循环、列表推导式,最后换成ThreadPoolExecutor后速度有提升,但离30分钟的目标还有差距,需要进一步优化。

具体优化建议

  • 调大线程池并发数:默认的线程数是CPU核心数的5倍,对于API调用这种IO密集型任务来说远远不够。可以手动设置max_workers参数,比如ThreadPoolExecutor(max_workers=50),甚至根据API的限流情况调到100左右(注意别触发对方的反限流机制)。
  • 复用HTTP连接:现在每次请求都新建TCP连接,握手和断开的开销很大。用requests.Session()来复用连接,把Session实例提前创建好,在函数里用session.get()代替requests.request(),能大幅减少网络耗时。
  • 尝试批量查询API:去查一下你调用的这个API是否支持一次性传入多个client_id,如果能批量请求,直接把7000个分成几批查,请求次数从7000降到几十,性能提升会非常明显。
  • 优化额外的API调用:get_subclient_backup_status和get_subclient_InstanceName这两个函数看起来是每个子客户端都要单独发请求,这会产生大量额外的网络请求。要么看看能不能在主请求里顺便拿到这些数据,要么把所有需要查的subclient_id收集起来批量查询,别单个请求。
  • 换成异步IO框架:用aiohttp代替requests,配合asyncio做异步请求,异步IO在处理大量网络等待时比线程池更高效,没有线程切换的开销,能进一步提升并发量。
  • 添加超时和重试:给请求加个合理的超时时间,比如timeout=10,避免某个慢请求卡住整个流程;同时给失败的请求加重试机制(比如用tenacity库),减少因网络波动导致的重试等待。
  • 简化JSON解析:requests自带的response.json()比手动json.loads(response.text)更高效,直接替换掉能省一点解析时间。
  • 提前生成静态数据:headers里的内容每次调用函数都重新生成,其实可以把headers移到函数外面,只生成一次,避免重复计算。

内容的提问来源于stack exchange,提问作者anormaluser

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.08 09:44:55