python fastApi 中的全局变量无法正常工作
python global variable in fastApi not working as normal
我有一个简单的 fastApi 演示应用程序,它实现了一个功能:
通过调用名为 changeResponse 的 post api 获得不同的响应 json。
changeResponse api 只是改变了一个全局变量,另一个 api return 不同的响应通过相同的全局 variable.On 本地环境,它工作正常,但响应总是在我之后改变当我在 docker.The 上构建它时调用 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,无法预测
tiangolo/uvicorn-gunicorn-fastapi
基于 uvicorn-gunicorn-docker image, which by defaults creates multiple workers. Excerpt from gunicorn_conf.py:
default_web_concurrency = workers_per_core * cores
因此,之所以会出现上述情况,是因为请求是由不同的worker(进程)处理的。每个都有自己的全局变量副本
更新:如果你想改变工人的数量,使用以下环境变量:
- WORKERS_PER_CORE:它会将worker的数量设置为CPU核的数量乘以这个值。
- MAX_WORKERS:您可以使用它让图像自动计算工人的数量,但要确保它限制在最大值。
- WEB_CONCURRENCY覆盖工人数量的自动定义。
你可以这样设置:
docker run -d -p 80:80 -e WEB_CONCURRENCY="2" myimage
这些变量和示例的更详细描述here
如果要在worker之间共享数据,注意这个。
我已经知道原因了:
the fastapi use uvicorn run the app, and use gunicorn to manage these uvicorn
the gunicorn in docker container default starts 2*num_of_core + 1 workers to run these uvicorn,so i assume there are three app in the server,and the request was sented to random worker to handle. that's why the response is random
reference:https://docs.gunicorn.org/en/stable/design.html
有同样的问题,在不更换工人的情况下得到解决。
app = FastAPI()
app.type = "00"
我认为这是最好的选择。
非常感谢参考:fastapi/issues/592
我有一个简单的 fastApi 演示应用程序,它实现了一个功能: 通过调用名为 changeResponse 的 post api 获得不同的响应 json。 changeResponse api 只是改变了一个全局变量,另一个 api return 不同的响应通过相同的全局 variable.On 本地环境,它工作正常,但响应总是在我之后改变当我在 docker.The 上构建它时调用 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,无法预测
tiangolo/uvicorn-gunicorn-fastapi
基于 uvicorn-gunicorn-docker image, which by defaults creates multiple workers. Excerpt from gunicorn_conf.py:
default_web_concurrency = workers_per_core * cores
因此,之所以会出现上述情况,是因为请求是由不同的worker(进程)处理的。每个都有自己的全局变量副本
更新:如果你想改变工人的数量,使用以下环境变量:
- WORKERS_PER_CORE:它会将worker的数量设置为CPU核的数量乘以这个值。
- MAX_WORKERS:您可以使用它让图像自动计算工人的数量,但要确保它限制在最大值。
- WEB_CONCURRENCY覆盖工人数量的自动定义。
你可以这样设置:
docker run -d -p 80:80 -e WEB_CONCURRENCY="2" myimage
这些变量和示例的更详细描述here
如果要在worker之间共享数据,注意这个
我已经知道原因了:
the fastapi use uvicorn run the app, and use gunicorn to manage these uvicorn the gunicorn in docker container default starts 2*num_of_core + 1 workers to run these uvicorn,so i assume there are three app in the server,and the request was sented to random worker to handle. that's why the response is random reference:https://docs.gunicorn.org/en/stable/design.html
有同样的问题,在不更换工人的情况下得到解决。
app = FastAPI()
app.type = "00"
我认为这是最好的选择。
非常感谢参考:fastapi/issues/592