RecursionError:在 Azure 上使用 Gunicorn 部署 Flask 应用程序时超出最大递归深度

问题描述 投票:0回答:1

我正在将 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 中的特定设置有关。

python azure flask websocket gunicorn
1个回答
0
投票

“/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
  • 从 Gunicorn 命令中删除
    --preload
    选项。此命令会在分叉工作进程之前预加载应用程序代码。这可能会导致在具有特定 SSL 配置的环境中出现递归错误

禁用 SSL 验证以查看递归问题是否与 SSL 处理直接相关。

response = http.request(
    'POST',
    url,
    body=encoded_payload,
    headers=headers,
    cert_reqs='CERT_NONE'  # Disable SSL verification
)
© www.soinside.com 2019 - 2024. All rights reserved.