简体   繁体   English

Uvicorn 和 Gunicorn+Uvicorn 有什么区别?

[英]What is the difference between Uvicorn and Gunicorn+Uvicorn?

What is the difference between deploying FastAPI apps dockerized using Uvicorn and Tiangolo's Gunicorn+Uvicorn ?使用 Uvicorn 和Tiangolo 的 Gunicorn+Uvicorn部署 FastAPI 应用程序有什么区别? And why do my results show that I get a better result when deploying only using Uvicorn than Gunicorn+Uvicorn?为什么我的结果显示仅使用 Uvicorn 部署时比 Gunicorn+Uvicorn 获得更好的结果?

When I searched in Tiangolo's documentation, it says:当我在 Tiangolo 的文档中搜索时,它说:

You can use Gunicorn to manage Uvicorn and run multiple of these concurrent processes.您可以使用 Gunicorn 来管理 Uvicorn 并运行多个这些并发进程。 That way, you get the best of concurrency and parallelism.这样,您可以获得最好的并发性和并行性。

From this, can I assume that using this Gunicorn will get a better result?由此,我可以假设使用这个 Gunicorn 会得到更好的结果吗?

This is my testing using JMeter.这是我使用 JMeter 进行的测试。 I deployed my script to Google Cloud Run, and this is the result:我将脚本部署到 Google Cloud Run,结果如下:

Using Python and Uvicorn:使用 Python 和 Uvicorn:

在此处输入图像描述

Using Tiangolo's Gunicorn+Uvicorn:使用 Tiangolo 的 Gunicorn+Uvicorn:

在此处输入图像描述

This is my Dockerfile for Python (Uvicorn):这是我的 Dockerfile 用于 Python(Uvicorn):

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"]

This is my Dockerfile for Tiangolo's Gunicorn+Uvicorn:这是我用于 Tiangolo 的 Gunicorn+Uvicorn 的 Dockerfile:

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

You can see the error from Tiangolo's Gunicorn+Uvicorn.您可以从 Tiangolo 的 Gunicorn+Uvicorn 看到错误。 Is it caused by Gunicorn?是Gunicorn引起的吗?

Edited.已编辑。

So, in my case, I using lazy load method to load my Machine Learning model.所以,就我而言,我使用延迟加载方法来加载我的机器学习 model。 This is my class to load the model.这是我的 class 加载 model。

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

And, this is my endpoint for my API.而且,这是我的 API 的端点。

@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)

Gunicorn is an application server supports the WSGI standard. Gunicorn是一个支持WSGI标准的应用服务器。 This means that Gunicorn can serve applications written in Flask or Django.这意味着 Gunicorn 可以为用 Flask 或 Django 编写的应用程序提供服务。The way it works is that it creates and maintains their operability a configurable number of application instances (aka workers) that serve requests from clients.它的工作方式是创建和维护它们的可操作性,可配置数量的应用程序实例(又名工作者)为来自客户端的请求提供服务。 Gunicorn itself is not compatible with FastAPI because FastAPI uses the fresh ASGI standard. Gunicorn 本身与 FastAPI 不兼容,因为 FastAPI 使用新的ASGI标准。

Uvicorn is an app server supports the ASGI protocol. Uvicorn是一个支持ASGI协议的应用服务器。 However, it's capabilities as a process (workers) manager leave much to be desired.但是,它作为流程(工人)经理的能力还有很多不足之处。

But Uvicorn has a Gunicorn-compatible worker class .但是 Uvicorn 有一个Gunicorn 兼容的工人 class Using that combination, Gunicorn would act as a process manager, listening on the port and the IP.使用这种组合,Gunicorn 将充当进程管理器,监听端口和 IP。 And it would transmit the communication to the worker processes running the Uvicorn class.它会将通信传输到运行 Uvicorn class 的工作进程。 And then the Gunicorn-compatible Uvicorn worker class would be in charge of converting the data sent by Gunicorn to the ASGI standard for FastAPI to use it.然后与 Gunicorn 兼容的 Uvicorn 工作人员 class 将负责将 Gunicorn 发送的数据转换为 ASGI 标准以供 FastAPI 使用。

If you have a cluster of machines with Kubernetes, Docker Swarm or another similar complex system to manage distributed containers on multiple machines, then you will probably want to handle replication at the cluster level instead of using a process manager (like Gunicorn with workers) in each container.如果您有一个机器集群,其中包含 Kubernetes、Docker Swarm 或其他类似的复杂系统来管理多台机器上的分布式容器,那么您可能希望在集群级别处理复制,而不是在每个容器。 One of those distributed container management systems like Kubernetes normally has some integrated way of handling replication of containers while still supporting load balancing for the incoming requests.像 Kubernetes 这样的分布式容器管理系统之一通常具有一些处理容器复制的集成方式,同时仍支持传入请求的负载平衡。 All at the cluster level.全部在集群级别。 In those cases, you would probably want to build a Docker image from scratch, installing your dependencies, and running a single Uvicorn process instead of running something like Gunicorn with Uvicorn workers.在这些情况下,您可能希望从头开始构建 Docker 映像,安装您的依赖项,并运行单个 Uvicorn 进程,而不是使用 Uvicorn 工作者运行诸如 Gunicorn 之类的东西。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 getIdToken 和 getAppCheckToken 有什么区别? - What is difference between the getIdToken and getAppCheckToken? gcloud 和 gsutil 有什么区别? - What is the difference between gcloud and gsutil? Cloud Build 和 Cloud Deploy 有什么区别? - What is the difference between Cloud Build and Cloud Deploy? GCP 云作曲家和工作流有什么区别? - What is the difference between GCP cloud composer and workflow? AWS Amplify 中的 currentAuthenticatedUser() 和 currentUserPoolUser() 有什么区别? - what is difference between currentAuthenticatedUser() and currentUserPoolUser() in AWS Amplify? Ballerina 中的 final 和 const 有什么区别? - What is the difference between final and const in Ballerina? Amazon SNS 和 Amazon SQS 有什么区别? - What is the difference between Amazon SNS and Amazon SQS? Auth.currentAuthenticatedUser() 和 Auth.currentSession() 有什么区别? - What is the difference between Auth.currentAuthenticatedUser() and Auth.currentSession()? boto3 中的 terminate_instances() 和 terminate() 有什么区别? - What is the difference between terminate_instances() and terminate() in boto3? GCP 中的服务帐户和服务代理有什么区别 - What is the difference between service account and service agent in GCP
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM