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

Gunicorn多线程Python应用调用GCP云函数的SSL连接异常问题

问题描述

我在App Engine上部署了一个Python应用,使用Gunicorn的gthread worker启动,启动命令为:

gunicorn -w 4 --threads 16 src.main:app

应用中通过requests.post(url, json=payload)调用GCP云函数,但通过Bugsnag报错持续出现以下SSL错误:

HTTPSConnectionPool(host='GCP CLOUD FUNCTION', port=443): Max retries exceeded with url: /path (Caused by SSLError(SSLZeroReturnError(6, 'TLS/SSL connection has been closed (EOF) (_ssl.c:997)')))

当前环境:Python 3.11、requests 2.28.2、urllib3 1.26.15

已尝试的方案:

  • 起初认为是证书问题,设置verify=False后错误消失,但该问题也出现在Bugsnag、Google Cloud Storage等无法禁用该参数的库中
  • 降低应用每分钟调用频率后问题仍存在
  • 更新Python及依赖也未解决
  • 移除Gunicorn启动命令中的--threads参数,错误不再出现

疑问:

  1. Python requests是否支持多线程环境?此前查询得知只要不跨线程复用requests.Session即可,但我并未这么做,难道requests底层使用了全局Session?
  2. 如何在保留多线程的前提下解决该SSL异常问题?

解答

1. Requests对多线程的支持

Requests本身支持多线程环境,核心规则确实是不要在多个线程间复用同一个requests.Session实例。但你遇到的问题,根源在于直接调用requests.post这类无Session的请求时,底层会使用一个全局默认Session——这个Session是线程不安全的,它会在所有线程间共享连接池,当多线程并发请求时,很容易出现连接被意外关闭、SSL握手失败等冲突,这就是你看到SSLZeroReturnError的原因。

2. 保留多线程的解决方案

(1)为每个线程/请求创建独立Session

不要再直接用requests.post,而是为每个线程或者每个Web请求创建专属的requests.Session,确保每个线程的连接池独立:

# 示例:在线程逻辑内创建专属Session
def process_request(url, payload):
    with requests.Session() as session:
        response = session.post(url, json=payload)
        # 处理响应逻辑

如果是在Flask/Django这类Web框架中,可以在请求上下文内初始化Session,保证每个请求对应独立的连接池,避免线程间冲突。

(2)调整urllib3连接池配置

Requests依赖urllib3的连接池,你可以通过自定义HTTPAdapter来调整连接池参数,减少复用冲突:

from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry

# 创建Session并配置适配器
session = requests.Session()
# 限制连接池大小,搭配重试机制
adapter = HTTPAdapter(
    pool_connections=4, 
    pool_maxsize=8,
    max_retries=Retry(total=3, backoff_factor=0.1)
)
session.mount('https://', adapter)

如果并发量不高,也可以直接设置pool_connections=1和pool_maxsize=1,强制每次请求新建连接,彻底避免连接复用冲突(但会牺牲一定性能)。

(3)升级urllib3版本

你当前使用的urllib3 1.26.15在多线程连接池管理上存在一些已知问题,建议升级到urllib3 1.26系列的最新版,或者升级Requests到2.31.0+后使用urllib3 2.x版本——新版本对多线程环境下的连接池竞争做了优化,能有效减少这类SSL连接异常。

(4)适当降低Gunicorn线程数

如果上述方法效果有限,可以尝试降低--threads参数值(比如从16调整到8),减少线程并发量,降低连接池的竞争压力,也能缓解SSL连接关闭的问题。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.24 02:23:12