首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >Uvicorn和Gunicorn+Uvicorn有什么区别?

Uvicorn和Gunicorn+Uvicorn有什么区别?
EN

Stack Overflow用户
提问于 2021-02-25 03:57:40
回答 1查看 6.5K关注 0票数 17

使用Uvicorn和天格洛氏Gunicorn+Uvicorn进行托管的天格洛氏Gunicorn+Uvicorn应用程序的部署有什么区别?为什么我的结果显示,仅使用Uvicorn部署的结果要比Gunicorn+Uvicorn更好?

当我在天格洛的文档中搜索时,它说:

您可以使用Gunicorn来管理Uvicorn并运行这些并发进程中的多个。这样,就可以充分利用并发性和并行性。

由此,我可以假设使用这个Gunicorn会得到一个更好的结果吗?

这是我使用JMeter进行的测试。我将脚本部署到Google运行中,结果是:

使用Python和Uvicorn:

使用Tiangolo的Gunicorn+Uvicorn:

这是我的Python Dockerfile (Uvicorn):

代码语言:javascript
运行
复制
FROM python:3.8-slim-buster
RUN apt-get update --fix-missing
RUN DEBIAN_FRONTEND=noninteractive apt-get install -y libgl1-mesa-dev python3-pip git
RUN mkdir /usr/src/app
WORKDIR /usr/src/app
COPY ./requirements.txt /usr/src/app/requirements.txt
RUN pip3 install -U setuptools
RUN pip3 install --upgrade pip
RUN pip3 install -r ./requirements.txt --use-feature=2020-resolver
COPY . /usr/src/app
CMD ["python3", "/usr/src/app/main.py"]

这是Tiangolo的Gunicorn+Uvicorn的Dockerfile:

代码语言:javascript
运行
复制
FROM tiangolo/uvicorn-gunicorn-fastapi:python3.8-slim
RUN apt-get update && apt-get install wget gcc -y
RUN mkdir -p /app
WORKDIR /app
COPY ./requirements.txt /app/requirements.txt
RUN python -m pip install --upgrade pip
RUN pip install --no-cache-dir -r /app/requirements.txt
COPY . /app

您可以从Tiangolo的Gunicorn+Uvicorn中看到错误。是由Gunicorn引起的吗?

编辑。

因此,在我的例子中,我使用延迟加载方法来加载我的机器学习模型。这是我的类来加载模型。

代码语言:javascript
运行
复制
class MyModelPrediction:
    # init method or constructor
    def __init__(self, brand):
        self.brand = brand

    # Sample Method
    def load_model(self):
        pathfile_model = os.path.join("modules", "model/")
        brand = self.brand.lower()
        top5_brand = ["honda", "toyota", "nissan", "suzuki", "daihatsu"]

        if brand not in top5_brand:
            brand = "ex_Top5"
            with open(pathfile_model + f'{brand}_all_in_one.pkl', 'rb') as file:
                brand = joblib.load(file)
        else:
            with open(pathfile_model + f'{brand}_all_in_one.pkl', 'rb') as file:
                brand = joblib.load(file)

        return brand

这是我的API端点。

代码语言:javascript
运行
复制
@router.post("/predict", response_model=schemas.ResponsePrediction, responses={422: schemas.responses_dict[422], 400: schemas.responses_dict[400], 500: schemas.responses_dict[500]}, tags=["predict"], response_class=ORJSONResponse)
async def detect(
    *,
    # db: Session = Depends(deps.get_db_api),
    car: schemas.Car = Body(...),
    customer_id: str = Body(None, title='Customer unique identifier')
) -> Any:
    """
    Predict price for used vehicle.\n
    """
    global list_detections
    try:
        start_time = time.time()
        brand = car.dict()['brand']
        obj = MyModelPrediction(brand)

        top5_brand = ["honda", "toyota", "nissan", "suzuki", "daihatsu"]
        if brand not in top5_brand:
            brand = "non"

        if usedcar.price_engine_4w[brand]:
            pass
        else:
            usedcar.price_engine_4w[brand] = obj.load_model()
            print("Load success")

        elapsed_time = time.time() - start_time
        print(usedcar.price_engine_4w)
        print("ELAPSED MODEL TIME : ", elapsed_time)

        list_detections = await get_data_model(**car.dict())

        if list_detections is None:
            result_data = None
        else:
            result_data = schemas.Prediction(**list_detections)
            result_data = result_data.dict()

    except Exception as e:  # noqa
        raise HTTPException(
            status_code=500,
            detail=str(e),
        )
    else:
        if result_data['prediction_price'] == 0:
            raise HTTPException(
                status_code=400,
                detail="The system cannot process your request",
            )
        else:
            result = {
                'code': 200,
                'message': 'Successfully fetched data',
                'data': result_data
            }

    return schemas.ResponsePrediction(**result)
EN

回答 1

Stack Overflow用户

发布于 2022-03-20 12:41:30

古尼坎是一个支持WSGI标准的应用服务器。这意味着Gunicorn可以为用Flask或Django等框架编写的应用程序提供服务(2021年以前发布的版本更适合)。它的工作方式是指它创建并维护它们的可操作性,这是一个可配置的应用程序实例(也称为工作实例),它为客户端的请求提供服务。Gunicorn本身与FastAPI不兼容,因为FastAPI使用了新的阿斯吉标准。

乌维霍恩是一个支持阿斯吉协议的应用服务器。然而,作为一个过程(工人)经理,它的能力还有很多需要改进的地方。

但是Uvicorn有一个与Gunicorn兼容的工薪阶层。使用这种组合,Gunicorn将充当进程管理器,监听端口和IP。它将把通信发送给运行Uvicorn类的工作进程。然后,与Gunicorn兼容的Uvicorn工人类将负责将Gunicorn发送的数据转换为FastAPI使用的ASGI标准。

如果您有一个具有Kubernetes、Docker或其他类似复杂系统的集群来管理多台机器上的分布式容器,那么您可能希望在集群级别处理复制,而不是在每个容器中使用流程管理器(比如Gunicorn和workers)。像Kubernetes这样的分布式容器管理系统通常有一些处理容器复制的集成方法,同时仍然支持传入请求的负载平衡。都在集群级别。在这些情况下,您可能希望从头构建一个Docker映像,安装您的依赖项,并运行一个Uvicorn进程,而不是使用Uvicorn工人运行Gunicorn之类的程序。

票数 11
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/66362199

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档