← Назад к вопросам

Какие знаешь 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/2HTTP/3WebSocketСкоростьСложность
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 сервера

  1. Uvicorn: для простых приложений, максимальная скорость
  2. Hypercorn: если нужны HTTP/2 или HTTP/3
  3. Daphne: для Django Channels WebSocket приложений
  4. Quart: полнофункциональный фреймворк вместо FastAPI

Production рекомендации

  • Используй Uvicorn с Nginx reverse proxy
  • 1-2 worker'а на CPU core
  • Мониторь метрики через Prometheus
  • Логируй в JSON для удобного парсинга
  • Используй healthcheck'и для балансировщиков нагрузки
  • Настрой graceful shutdown (обработка SIGTERM)
Какие знаешь ASGI серверы? | PrepBro