我目前正在 Django 中开发一个服务,它使用一个缓慢的外部 API(需要大约 10 秒才能获得响应),这意味着与我的服务器的连接保持打开状态,等待外部 API 响应,并占用工作时间/资源。
我知道我可以使用 gunicorn 的线程或 gevent 工作人员来添加并发性,但似乎无法掌握将 gunicorn 与 gevent 工作人员一起使用和将 uvicorn(或任何其他服务器)与 asgi 接口一起使用之间的确切区别。
使用其中一种的标准是什么?
Django 仍然不完全支持 async/await 视图。如果我坚持使用 gevent 工人会更好吗?
我一直在修改 Flask 和 FastAPI 以了解它如何充当服务器。
我想知道的主要事情之一是 Flask 和 FastAPI 如何处理来自多个客户端的多个请求。
特别是当代码有效率问题时(数据库查询时间长)。
所以,我尝试制作一个简单的代码来理解这个问题。
代码很简单,当客户端访问路由时,应用程序休眠10秒才返回结果。
它看起来像这样:
快速API
import uvicorn
from fastapi import FastAPI
from time import sleep
app = FastAPI()
@app.get('/')
async def root():
print('Sleeping for 10')
sleep(10)
print('Awake')
return {'message': 'hello'}
if __name__ == "__main__":
uvicorn.run(app, host="127.0.0.1", port=8000)
Run Code Online (Sandbox Code Playgroud)
烧瓶
from flask import Flask
from flask_restful import Resource, Api
from time import sleep
app = Flask(__name__)
api = Api(app)
class Root(Resource):
def get(self):
print('Sleeping for 10')
sleep(10)
print('Awake')
return {'message': 'hello'}
api.add_resource(Root, …Run Code Online (Sandbox Code Playgroud) 这真的很令人沮丧,我确实根据文档设置了所有内容,但是当我尝试独立运行 daphne 时,它不断抛出错误,当我使用python manage.py run server. 这非常令人沮丧,我似乎在其他任何地方都找不到类似的错误
2020-01-25 09:57:17,627 INFO Starting server at tcp:port=8000:interface=127.0.0.1
2020-01-25 09:57:17,628 INFO HTTP/2 support not enabled (install the http2 and tls Twisted extras)
2020-01-25 09:57:17,628 INFO Configuring endpoint tcp:port=8000:interface=127.0.0.1
2020-01-25 09:57:17,629 INFO Listening on TCP address 127.0.0.1:8000
127.0.0.1:44516 - - [25/Jan/2020:09:57:27] "WSCONNECTING /ws/score/" - -
2020-01-25 09:57:28,637 ERROR Exception inside application: Django can only handle ASGI/HTTP connections, not websocket.
File "/home/sofdeath/.local/lib/python3.7/site-packages/daphne/cli.py", line 30, in asgi
await self.app(scope, receive, send)
File "/home/sofdeath/.local/lib/python3.7/site-packages/django/core/handlers/asgi.py", line 146, …Run Code Online (Sandbox Code Playgroud) 我们正在使用 fastapi、uvicorn、sqlalchemy 和 PostgreSQL 构建 ASGI 应用程序。问题是:与具有多个工作线程的 WSGI 应用程序相比,我们应该如何设置pool_size才能create_async_engine不使其成为瓶颈?
据我了解,在 WSGI 应用程序中,如果我们使用每个(和)线程运行N进程,我们将获得最多连接。但是 ASGI 怎么样(如果我们有一个进程)——可以打开多少个连接?另外(因为我们每个进程只创建一个)?那么我们应该将其设置为?Mpool_size=MN * Mpool_sizeAsyncEnginepool_size=N * M
而且,如果我们简单地增加这个数字,那么我们就能够await向数据库发出更多的并发请求,对吧?
其背后的直觉是什么?
提前致谢!
鉴于此示例 Starlette 应用程序具有开放的 websocket 连接,您如何关闭 Starlette 应用程序?我在 uvicorn 上运行。每当我按下Ctrl+C输出时,Waiting for background tasks to complete.它就会永远挂起。
from starlette.applications import Starlette
app = Starlette()
@app.websocket_route('/ws')
async def ws(websocket):
await websocket.accept()
while True:
# How to interrupt this while loop on the shutdown event?
await asyncio.sleep(0.1)
await websocket.close()
Run Code Online (Sandbox Code Playgroud)
我尝试在关闭事件上切换 bool 变量,但该变量永远不会更新。它总是False。
例如。
app.state.is_shutting_down = False
@app.on_event('shutdown')
async def shutdown():
app.state.is_shutting_down = True
@app.websocket_route('/ws')
async def ws(websocket):
await websocket.accept()
while app.state.is_shutting_down is False:
Run Code Online (Sandbox Code Playgroud) 问题简述
我已将我的项目从 Django 2.2 迁移到 Django 3.2,现在我想开始使用异步视图的可能性。我创建了一个异步视图,设置了 asgi 配置,并使用 Uvicorn 工作程序运行 Gunicorn。当该服务器同时有 10 个用户时,他们会被同步服务。我需要配置什么才能为 10 个并发用户提供异步视图?
详细问题
这是我到目前为止在本地环境中所做的:
gunicorn并uvicorn通过 pipasgi.py包含以下内容的文件 import os
from django.core.asgi import get_asgi_application
os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'MyService.settings.local')
application = get_asgi_application()
Run Code Online (Sandbox Code Playgroud)
urlpatterns: import asyncio
import json
from django.http import HttpResponse
async def async_sleep(request):
await asyncio.sleep(1)
return HttpResponse(json.dumps({'mode': 'async', 'time': 1).encode())
Run Code Online (Sandbox Code Playgroud)
gunicorn MyService.asgi:application -k uvicorn.workers.UvicornWorker
[2022-01-26 14:37:14 +0100] [8732] [INFO] Starting …Run Code Online (Sandbox Code Playgroud) 我有一个应用程序位于具有配置的Django服务器中。现在我也必须一起工作。在本地计算机上一切都很好,但我读过很多关于 Django Channels 与 uwsgi 不兼容的内容。NginxuwsgiDjango Channels
nginx.conf我尝试多次以多种不同的方式配置代理,Daphne但对我来说没有任何作用。我有这个问题几个月了,但我找不到任何可以帮助我的东西。
设置.py
# WSGI
WSGI_APPLICATION = 'config.wsgi.application'
# Channels
ASGI_APPLICATION = 'config.routing.application'
CHANNEL_LAYERS = {
'default': {
'BACKEND': 'channels_redis.core.RedisChannelLayer',
'CONFIG': {
"hosts": [('127.0.0.1', 6379)],
},
},
}
Run Code Online (Sandbox Code Playgroud)
配置.路由.py
from channels.auth import AuthMiddlewareStack
from channels.routing import ProtocolTypeRouter, URLRouter
import myproject.websocket.routing
application = ProtocolTypeRouter({
'websocket': AuthMiddlewareStack(
URLRouter(
myproject.websocket.routing.websocket_urlpatterns
)
)
})
Run Code Online (Sandbox Code Playgroud)
网络套接字网址
from django.urls import re_path
from . import consumers
websocket_urlpatterns = [
re_path(r'ws/socket/$', consumers.WebSocketConsumer),
]
Run Code Online (Sandbox Code Playgroud)
阿斯吉 …
我想定义一个从文本文件生成的 dict 变量一次,并用它来响应 API 请求。
该变量应该始终可用,直到服务器运行结束。
在下面的示例中:
from fastapi import FastAPI
import uvicorn
app = FastAPI()
def init_data(path):
print("init call")
data = {}
data[1] = "123"
data[2] = "abc"
return data
data = init_data('path')
@app.get('/')
def example_method():
# data is defined
return {'Data': data[1]}
if __name__ == '__main__':
uvicorn.run(f'example_trouble:app', host='localhost', port=8000)
Run Code Online (Sandbox Code Playgroud)
我会得到:
init call
init call
INFO: Started server process [9356]
INFO: Waiting for application startup.
INFO: Application startup complete.
INFO: Uvicorn running on http://localhost:8000 (Press CTRL+C to quit)
Run Code Online (Sandbox Code Playgroud)
向 …