FastAPI 中的 Python 全局变量无法正常工作

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

我有一个简单的FastAPI演示应用程序,它实现了一个功能: 通过调用名为

changeResponse
的 post api 获取不同的响应 json。
changeResponse
api 只是更改了一个全局变量,另一个 api 通过相同的全局变量返回不同的响应。在本地环境中,它工作正常,但是当我在 docker 上构建它时,我只调用一次
changeResponse
后,响应总是会发生变化。代码如下:

from typing import Optional
from fastapi import FastAPI
from util import read_json
import enum

app = FastAPI()

type = "00"
    
@app.post("/changeResponse")
async def handle_change_download_response(param:Optional[str]):
        global type
        type = param
        print("type is "+type)
        return {"success":"true"}

@app.post("/download")
async def handle_download(param:Optional[str]):
    print("get download param: "+param)
    if legalDownload(param):
        print("type is "+type)
        return read_json.readDownloadSuccessRes(type)
    else:
        return read_json.readDownloadFailRes()

def legalDownload(data:str)->bool:
    return True

dockerfile如下:

FROM tiangolo/uvicorn-gunicorn-fastapi:python3.7

COPY ./app /app

我除了什么: 调用

changeResponse
参数为 7,得到 7 的响应, 调用
changeResponse
参数为 8,得到 8 的响应。 我得到什么: 调用
changeResponse
参数是7,得到7的响应,调用
changeReponse
8,有时响应是7,有时是8,无法预测

python python-3.x docker fastapi uvicorn
3个回答
11
投票

tiangolo/uvicorn-gunicorn-fastapi
基于uvicorn-gunicorn-docker镜像,默认情况下会创建多个worker。摘自gunicorn_conf.py

default_web_concurrency = workers_per_core * cores

因此,出现所描述的情况是因为请求是由不同的工作人员(进程)处理的。每个都有自己的全局变量副本

更新:如果要更改工作人员数量,请使用以下环境变量:

  • WORKERS_PER_CORE:它将设置工作线程数为CPU核心数乘以该值。
  • MAX_WORKERS:您可以使用它让图像自动计算工人数量,但确保其限制在最大值。
  • WEB_CONCURRENCY 覆盖工作人员数量的自动定义。

您可以这样设置:

docker run -d -p 80:80 -e WEB_CONCURRENCY="2" myimage

这些变量和示例的更详细描述这里


如果你想在worker之间共享数据,请关注这个主题


11
投票

遇到了同样的问题,并且在不更换工人的情况下得到了解决。

app = FastAPI()

app.type = "00"

我认为这是最好的选择。

非常感谢参考:fastapi/issues/592


0
投票

我已经知道为什么了:

fastapi使用uvicorn运行应用程序,并使用gunicorn来管理这些uvicorn docker容器中的gunicorn默认启动2 * num_of_core + 1个worker来运行这些uvicorn,所以我假设服务器中有三个应用程序,并且请求被发送到随机worker来处理。这就是为什么响应是随机的 参考:https://docs.gunicorn.org/en/stable/design.html

© www.soinside.com 2019 - 2024. All rights reserved.