多实例运行Python Requests时请求速度骤慢的问题求助
解决多Python实例下requests请求缓慢/连接失败问题
问题根源分析
你的核心问题并非服务端限制,而是Python requests默认的连接池配置+多实例的资源竞争导致的:
- requests默认每个主机的连接池仅保留10个活跃连接(
pool_maxsize=10),多实例同时发起请求时,大量连接会处于排队等待状态,直接拖慢请求速度。 - 每个独立的Python进程会占用独立的文件句柄,当实例数过多时,系统可用文件句柄耗尽,会触发连接超时、重试失败的错误。
针对性解决方案
1. 调整requests连接池参数(适合保留多实例的场景)
给每个requests会话配置更大的连接池,同时调整重试策略:
import requests from requests.adapters import HTTPAdapter from urllib3.util.retry import Retry def create_session(): session = requests.Session() # 配置重试策略 retry_strategy = Retry( total=3, backoff_factor=1, status_forcelist=[429, 500, 502, 503, 504] ) # 配置连接池大小:pool_connections是缓存的连接池数量,pool_maxsize是每个池的最大连接数 adapter = HTTPAdapter( max_retries=retry_strategy, pool_connections=100, pool_maxsize=100 ) session.mount("http://", adapter) session.mount("https://", adapter) return session # 使用配置后的会话发起请求 session = create_session() url = f'http://myendpoint.app/api/v1' body = {"id": id, "action": "notifications"} try: response = session.get(url, json=body, timeout=15) response.raise_for_status() # 主动抛出HTTP错误 print(response.text) return response.json() except requests.exceptions.RequestException as e: print(f"请求失败: {e}")
2. 改用单进程异步框架(推荐,资源利用率更高)
放弃多实例模式,用aiohttp实现单进程多异步请求,共享连接池,大幅降低资源消耗:
import aiohttp import asyncio async def make_request(session, id): url = f'http://myendpoint.app/api/v1' body = {"id": id, "action": "notifications"} try: async with session.get(url, json=body, timeout=15) as response: response.raise_for_status() result = await response.json() print(result) return result except Exception as e: print(f"ID {id} 请求失败: {e}") async def main(client_ids): # 配置异步连接池 timeout = aiohttp.ClientTimeout(total=15) connector = aiohttp.TCPConnector(limit=100) # 最大并发连接数 async with aiohttp.ClientSession(timeout=timeout, connector=connector) as session: tasks = [make_request(session, cid) for cid in client_ids] await asyncio.gather(*tasks) # 替换为你的客户ID列表 client_ids = [1,2,3,...,800] asyncio.run(main(client_ids))
3. 调整系统文件句柄限制
多实例会占用大量文件句柄,检查并修改系统限制:
- Linux/macOS:
- 查看当前限制:
ulimit -n - 临时调整:
ulimit -n 4096(当前会话生效) - 永久调整:编辑
/etc/security/limits.conf,添加:* soft nofile 4096 * hard nofile 8192
- 查看当前限制:
- Windows:
通过组策略编辑器调整“进程打开的文件数”限制,路径:计算机配置>Windows设置>安全设置>本地策略>用户权限分配>增加进程工作集大小
关键注意事项
- 不要同时保留多实例+高并发异步,二者选其一即可,异步模式资源利用率远高于多实例。
- 即使调整了连接池,也不要把并发数设置得过高,需结合系统实际硬件资源调整,逐步测试找到最优值。
内容的提问来源于stack exchange,提问作者SrMilton
相关产品推荐
相关产品推荐

