Cloud Run中Python Requests调用API遇SSLZeroReturnError问题求助
问题分析与解决方案
核心原因
FastAPI的BackgroundTasks默认用线程池执行后台任务,当大量请求触发任务时,requests默认的连接池会因为连接复用不当、未及时释放,加上Cloud Run容器的套接字数量/连接超时限制,导致连接被中途关闭,出现SSLZeroReturnError。本地运行无问题是因为本地资源限制宽松,并发压力小。
具体解决方案
1. 用requests.Session复用连接并配置连接池参数
requests.Session会自动复用TCP连接,减少套接字创建量,同时可通过urllib3参数控制最大连接数,避免超限。
修改请求函数:
import requests from requests.adapters import HTTPAdapter from urllib3.util.retry import Retry # 服务启动时初始化全局Session,只创建一次 serper_session = requests.Session() # 配置重试策略与连接池参数 retry_strategy = Retry( total=3, backoff_factor=1, status_forcelist=[429, 500, 502, 503, 504], allowed_methods=["POST"] ) adapter = HTTPAdapter( max_retries=retry_strategy, pool_connections=10, # 控制同时打开的连接池数量 pool_maxsize=10 # 每个连接池的最大连接数 ) serper_session.mount("https://", adapter) def serper_search(self, arguments): query = arguments["q"] url = "https://google.serper.dev/search" payload = {"q": query} # 直接传字典,requests自动序列化JSON,无需手动dumps headers = { 'X-API-KEY': self.api_key, 'Content-Type': 'application/json' } try: # 使用全局Session发起请求 response = serper_session.post(url, headers=headers, json=payload) response.raise_for_status() # 读取内容后显式关闭连接,释放回连接池 response_content = response.json() response.close() parsed_response = self.parse_response(response_content, number_of_results=3) return parsed_response except requests.exceptions.HTTPError as http_err: logger.error(f"HTTP error occurred: {http_err}") return None except Exception as e: logger.error(f"Error occurred: {e}") return None
2. 限制BackgroundTasks的线程池大小
FastAPI默认后台任务线程池大小为CPU核心数*5,在Cloud Run容器环境中(通常核心数有限),手动调整线程池大小可避免并发任务过多导致连接超限。
修改FastAPI主文件:
from fastapi import FastAPI, BackgroundTasks from concurrent.futures import ThreadPoolExecutor # 自定义线程池,根据Cloud Run资源调整并发数(1核实例建议设为5-10) executor = ThreadPoolExecutor(max_workers=5) app = FastAPI() @app.post("/message", tags=["Main"]) async def handle_message(background_tasks: BackgroundTasks, message): # 用自定义线程池执行后台任务 background_tasks.add_task(executor.submit, serper_search, message) return {"success": True}
3. 显式释放响应资源
读取响应内容后调用response.close(),确保连接被释放回连接池,避免套接字泄漏。
4. 调整Cloud Run容器配置
- 提升CPU/内存配额:资源不足会导致连接处理不及时,被系统强制关闭
- 延长请求超时:在Cloud Run控制台设置更长的请求超时,避免后台任务未完成时连接被切断
验证逻辑
去掉BackgroundTasks时无错误,说明核心问题是后台任务的并发连接数超限,通过上述方案限制并发、复用连接后,可解决SSLZeroReturnError问题。
内容的提问来源于stack exchange,提问作者Ege
相关产品推荐
相关产品推荐

