← Назад к вопросам
Какие знаешь ASGI серверы?
2.0 Middle🔥 111 комментариев
#FastAPI и Flask#Асинхронность и многопоточность
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
ASGI серверы для Python приложений
ASGI (Asynchronous Server Gateway Interface) — стандарт для асинхронных Python веб-приложений. Вот основные ASGI серверы:
1. Uvicorn
Самый популярный и быстрый ASGI сервер.
# Запуск приложения FastAPI через Uvicorn
# Command line:
# uvicorn main:app --host 0.0.0.0 --port 8000 --workers 4
# Или программно:
import uvicorn
from fastapi import FastAPI
app = FastAPI()
@app.get("/")
async def root():
return {"message": "Hello"}
if __name__ == "__main__":
uvicorn.run(
"main:app",
host="0.0.0.0",
port=8000,
workers=4,
reload=True, # Перезагружать при изменении кода
log_level="info"
)
Особенности:
- Построен на uvloop (быстрее стандартного asyncio)
- Поддерживает HTTP/1.1 и WebSocket
- Легкий в развёртывании
- Быстрый инференс
2. Hypercorn
Альтернатива Uvicorn с поддержкой HTTP/2 и HTTP/3.
# Запуск
hypercorn main:app --bind 0.0.0.0:8000 --workers 4
# С SSL
hypercorn main:app \
--certfile ./certs/cert.pem \
--keyfile ./certs/key.pem \
--bind 0.0.0.0:8443
Особенности:
- HTTP/2 поддержка (пуш ресурсов, мультиплексирование)
- HTTP/3 (QUIC) поддержка (экспериментально)
- WebSocket поддержка
- HTTPS из коробки
3. Daphne
Сервер для Django Channels (WebSockets).
# Базовый запуск
daphne -b 0.0.0.0 -p 8000 myproject.asgi:application
# С reload
daphne -b 0.0.0.0 -p 8000 --verbosity 2 myproject.asgi:application
Особенности:
- Встроена поддержка Django
- Хорошо для WebSocket приложений
- Медленнее чем Uvicorn для чистого ASGI
4. Quart
ASGI фреймворк (не сервер, но работает с ASGI).
from quart import Quart, websocket
app = Quart(__name__)
@app.route("/")
async def hello():
return "Hello World"
@app.websocket("/ws")
async def ws():
while True:
data = await websocket.receive()
await websocket.send(data)
if __name__ == "__main__":
app.run(host="0.0.0.0", port=8000)
5. ASGI middleware и production setup
# Типичный production setup для FastAPI
import logging
from fastapi import FastAPI
from fastapi.middleware.cors import CORSMiddleware
from fastapi.middleware.gzip import GZIPMiddleware
from fastapi.middleware.trustedhost import TrustedHostMiddleware
app = FastAPI()
# CORS middleware
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"],
)
# Gzip compression
app.add_middleware(GZIPMiddleware, minimum_size=1000)
# Trusted hosts
app.add_middleware(
TrustedHostMiddleware,
allowed_hosts=["example.com", "www.example.com"]
)
# Custom middleware
from fastapi import Request
@app.middleware("http")
async def add_custom_headers(request: Request, call_next):
response = await call_next(request)
response.headers["X-Custom-Header"] = "value"
return response
6. Production Deployment Pattern
# Типичная production архитектура
# 1. Nginx (reverse proxy)
# /etc/nginx/nginx.conf
upstream fastapi_app {
server 127.0.0.1:8000;
server 127.0.0.1:8001;
server 127.0.0.1:8002;
server 127.0.0.1:8003;
}
server {
listen 80;
server_name example.com;
location / {
proxy_pass http://fastapi_app;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
}
# 2. Запуск Uvicorn с несколькими workers
# systemd service file: /etc/systemd/system/fastapi.service
[Unit]
Description=FastAPI Application
After=network.target
[Service]
Type=notify
User=www-data
Group=www-data
WorkingDirectory=/opt/app
ExecStart=/usr/bin/python3 -m uvicorn main:app \
--host 127.0.0.1 \
--port 8000 \
--workers 4
[Install]
WantedBy=multi-user.target
# Запуск:
# systemctl start fastapi
# systemctl enable fastapi
7. Сравнение ASGI серверов
| Сервер | HTTP/2 | HTTP/3 | WebSocket | Скорость | Сложность |
|---|---|---|---|---|---|
| Uvicorn | Нет | Нет | Да | Высокая | Низкая |
| Hypercorn | Да | Да (beta) | Да | Средняя | Средняя |
| Daphne | Нет | Нет | Да | Низкая | Низкая |
| Quart | Да | Нет | Да | Средняя | Высокая |
8. Docker с ASGI сервером
# Dockerfile
FROM python:3.11-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
# Health check
HEALTHCHECK --interval=30s --timeout=10s --start-period=40s --retries=3 \
CMD python -c "import requests; requests.get('http://localhost:8000/health')"
CMD ["uvicorn", "main:app", "--host", "0.0.0.0", "--port", "8000", "--workers", "4"]
# docker-compose.yml
version: '3.8'
services:
app:
build: .
ports:
- "8000:8000"
environment:
- DEBUG=false
- WORKERS=4
restart: unless-stopped
nginx:
image: nginx:alpine
ports:
- "80:80"
- "443:443"
volumes:
- ./nginx.conf:/etc/nginx/nginx.conf
depends_on:
- app
9. Мониторинг и логирование
import logging
from pythonjsonlogger import jsonlogger
# JSON логирование
logHandler = logging.StreamHandler()
formatter = jsonlogger.JsonFormatter()
logHandler.setFormatter(formatter)
logger = logging.getLogger()
logger.addHandler(logHandler)
logger.setLevel(logging.INFO)
# Использование в приложении
from fastapi import FastAPI
from pythonjsonlogger import jsonlogger
app = FastAPI()
@app.get("/api/data")
async def get_data():
logger.info("Getting data", extra={"user_id": 123})
return {"data": "some data"}
# Prometheus метрики
from prometheus_client import Counter, Histogram, start_http_server
import time
# Метрики
request_count = Counter(
'app_requests_total',
'Total requests',
['method', 'endpoint', 'status']
)
request_duration = Histogram(
'app_request_duration_seconds',
'Request duration',
['method', 'endpoint']
)
# Middleware для метрик
@app.middleware("http")
async def add_metrics(request: Request, call_next):
start_time = time.time()
response = await call_next(request)
duration = time.time() - start_time
request_count.labels(
method=request.method,
endpoint=request.url.path,
status=response.status_code
).inc()
request_duration.labels(
method=request.method,
endpoint=request.url.path
).observe(duration)
return response
if __name__ == "__main__":
# Запустить Prometheus endpoint на порту 8001
start_http_server(8001)
uvicorn.run(app, host="0.0.0.0", port=8000)
Выбор ASGI сервера
- Uvicorn: для простых приложений, максимальная скорость
- Hypercorn: если нужны HTTP/2 или HTTP/3
- Daphne: для Django Channels WebSocket приложений
- Quart: полнофункциональный фреймворк вместо FastAPI
Production рекомендации
- Используй Uvicorn с Nginx reverse proxy
- 1-2 worker'а на CPU core
- Мониторь метрики через Prometheus
- Логируй в JSON для удобного парсинга
- Используй healthcheck'и для балансировщиков нагрузки
- Настрой graceful shutdown (обработка SIGTERM)