我正在将 Flask 应用程序部署到 Azure,并且遇到了仅在部署应用程序时才会出现的 RecursionError:超出最大递归深度错误。相同的代码在本地运行得非常好。
错误信息:
“/opt/python/3.10.14/lib/python3.10/ssl.py”,第 604 行,最小版本 super(SSLContext, SSLContext).minimum_version.set(self, value) [上一行又重复了 476 次] RecursionError:超出最大递归深度 ”
这是我的代码的相关部分:
http = urllib3.PoolManager()
encoded_payload = urllib.parse.urlencode(payload).encode('utf-8')
response = http.request('POST', url, body=encoded_payload, headers=headers)
response_data = json.loads(response.data.decode('utf-8'))
部署配置: 我正在使用 Gunicorn 在 Azure 上部署应用程序。这是我的启动配置:
Azure 中的启动命令:
gunicorn --bind=0.0.0.0:8000 --timeout 600 --worker-class gevent --preload app:app
我也有这个startup.txt:
gunicorn --bind=0.0.0.0:8000 --timeout 600 --worker-class gevent app:app
当我在 Azure 中删除启动命令时,请求成功,但涉及 WebSocket 的其他代码部分停止工作。
该错误不会在本地发生,仅当应用程序部署在 Azure 上时才会发生。我认为递归错误似乎与 SSL 上下文创建和处理有关,但我不确定为什么这会导致递归循环。
更新
我最初使用机密 URL 遇到此问题,但我能够使用公共 API 重现相同的 RecursionError。以下是问题的最小重现。
设置烧瓶应用程序:
创建一个基本的 Flask 应用程序,其端点使用 urllib3 触发 HTTP POST 请求。
from flask import Flask, jsonify
import urllib3
import urllib.parse
import json
import traceback
app = Flask(__name__)
@app.route('/')
def index():
url = "https://jsonplaceholder.typicode.com/posts" # Public API for testing
payload = {
"title": "foo",
"body": "bar",
"userId": 1
}
headers = {
"accept": "application/json",
"Content-type": "application/json" # JSON content type for this API
}
try:
http = urllib3.PoolManager()
encoded_payload = json.dumps(payload).encode('utf-8') # JSON payload for the public API
response = http.request(
'POST',
url,
body=encoded_payload,
headers=headers
)
response_data = json.loads(response.data.decode('utf-8'))
return jsonify(response_data)
except Exception as e:
traceback.print_exc()
return jsonify({"error": str(e), "trace": traceback.format_exc()}), 500
if __name__ == '__main__':
app.run(debug=True)
使用 Gunicorn 将 Flask 应用程序部署到 Azure:
使用 Gunicorn 将应用程序部署到 Azure。这是我使用的启动命令:
gunicorn --bind=0.0.0.0:8000 --timeout 600 --worker-class gevent --preload app:app
startup.txt 文件: Gunicorn --bind=0.0.0.0:8000 --timeout 600 --worker-class gevent app:app
重现问题: 将应用程序部署到 Azure 并访问根终结点 (/)。这应该会触发 RecursionError:超出最大递归深度错误。
预期行为与实际行为:
预期行为:应用程序应处理请求并从公共 API 返回预期的 JSON 响应。 实际行为:应用程序引发 RecursionError,看似与 SSL 上下文处理相关,但根本原因可能在代码中的其他地方。
注:
我最初使用的公共 API 和机密 URL 都会出现此错误,表明该问题可能与使用 Gunicorn 时的部署环境或 Azure 中的特定设置有关。
“/opt/python/3.10.14/lib/python3.10/ssl.py”,第 604 行,最小版本 super(SSLContext, SSLContext).minimum_version.set(self, value) [上一行又重复了 476 次] RecursionError:超出最大递归深度 ”
在 Gunicorn 中使用特定配置时会出现此问题,例如
gevent
工作类和 --preload
选项。
gevent
工作者类会在某些环境中导致SSL问题,从而导致递归错误。这是因为 gevent
改变了 I/O 操作(包括 SSL 处理)的管理方式。切换到
sync
或 eventlet
工作线程类,这可能会以不同的方式处理 SSL。
gunicorn --bind=0.0.0.0:8000 --timeout 600 --worker-class sync app:app
--preload
选项。此命令会在分叉工作进程之前预加载应用程序代码。这可能会导致在具有特定 SSL 配置的环境中出现递归错误禁用 SSL 验证以查看递归问题是否与 SSL 处理直接相关。
response = http.request(
'POST',
url,
body=encoded_payload,
headers=headers,
cert_reqs='CERT_NONE' # Disable SSL verification
)