如何在 Heroku 中 运行 UVICORN?

How to run UVICORN in Heroku?

所以我已经弄清楚如何编写 fastAPI 并且我准备将我的脚本部署到我使用过 fastAPI 的 heroku (https://fastapi.tiangolo.com/) 但是问题是当我向 heroku 发出请求时它只会 return:

<html>
  <head>
    <title>Internal Server Error</title>
  </head>
  <body>
    <h1><p>Internal Server Error</p></h1>

  </body>
</html>

这意味着脚本已打开,但我看不到错误,我会说它在本地工作得很好。

我看不到任何有问题的日志,但是我会说我的问题可能是我不确定我的 procfile 是否正确,因为我没有完全编辑了它,我对此很陌生,我在这里问我如何能够 运行 我的 fastapi 脚本在 heroku 中?

我所知道的是,要能够 运行 脚本,您必须使用命令 uvicorn main:app --reload,如果您使用 etc py main.py 我是什么做错了吗?

我已经测试了你的设置并经过一些检查(之前从未使用过 Heroku)我猜你的 uvicorn 从未绑定到指定的端口(heroku-cli 命令 heroku local 对你有用吗?)

您的 Procfile 可能如下所示;

web: uvicorn src.main:app --host=0.0.0.0 --port=${PORT:-5000}

这个例子假设你的源代码在一个名为 'src' 的子文件夹中,其中有一个空的 __init__.py(表示一个 Python 模块,你可能想将 src 添加到 PYTHONPATH相反,请参阅包含您的 fastapi 应用程序的 app.json) 和 main.py

import socket
import sys

from fastapi import FastAPI

app = FastAPI()

hostname = socket.gethostname()

version = f"{sys.version_info.major}.{sys.version_info.minor}"


@app.get("/")
async def read_root():
    return {
        "name": "my-app",
        "host": hostname,
        "version": f"Hello world! From FastAPI running on Uvicorn. Using Python {version}"
    }

我已将此示例添加到 github which you can view on heroku(目前)

您还可以将 Gunicorn 上的 FastAPI 配置为 运行,并将 uvicorn 作为工作进程。以下是您可以保留在 Heroku 使用的 Procfile 中的命令行,用于构建和 运行ning。下面的命令将在 3 个工作进程上启动你的应用程序

web: gunicorn -w 3 -k uvicorn.workers.UvicornWorker main:app

有关详细的分步视频,您可以访问此视频教程,其中详细介绍了如何 deploy FastAPI on Heroku in just 6 minutes. or you can have a detailed walkthrough of how to create and deploy python based FastAPI on Heroku from this blog post.

答案是正确的,但是在生产中使用 FastAPI 运行 作为 WSGIASGI 工人是一个更好的选择是为什么,我 运行 这个 的基准,所以这里是结果。

Gunicorn 与 Uvicorn 工人

Requests per second:    8665.48 [#/sec] (mean)
Concurrency Level:      500
Time taken for tests:   0.577 seconds
Complete requests:      5000
Time per request:       57.700 [ms] (mean)

纯粹的独角兽

Requests per second:    3200.62 [#/sec] (mean)
Concurrency Level:      500
Time taken for tests:   1.562 seconds
Complete requests:      5000
Time per request:       156.220 [ms] (mean)

如您所见,RPS(每秒请求数) 和每个请求的响应时间存在巨大差异。

Procfiles

Gunicorn 与 Uvicorn 工人

web: gunicorn -w 4 -k uvicorn.workers.UvicornWorker main:app

纯uvicorn

web: uvicorn main:app --workers 4

相比之下, 与纯 uvicorn 相比,uvicornworkers 处理速度更快,这使得 FastAPI 执行进程的速度比 Flask 快得多。

在生产中,建议使用 guincorn 和 Uvicornworkers

在 heroku Procfile 中,

web: gunicorn -k uvicorn.workers.UvicornWorker --bind 0.0.0.0:$PORT main:app

$PORT:不使用固定端口,建议使用动态端口

就我而言,我没有将 wsgi 应用程序更新为 asgi 应用程序。

当 运行:

gunicorn pm.wsgi --log-level=debug \
-k uvicorn.workers.UvicornWorker --log-file - --timeout 60

我得到了:

所以,我添加了 WSGIMiddleware:

import os

from django.core.wsgi import get_wsgi_application
from dj_static import Cling
from uvicorn.middleware.wsgi import WSGIMiddleware
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "pm.settings")

# added the WSGIMiddleWare wrapper
application = WSGIMiddleware(Cling(get_wsgi_application()))