Comment puis-je éviter la pression sur les ressources et les plantages potentiels lors d'appels HTTP simultanés dans un point de terminaison FastAPI ?

Mary-Kate Olsen
Libérer: 2024-11-15 22:02:02
original
412 Les gens l'ont consulté

How can I avoid resource strain and potential crashes when making concurrent HTTP calls in a FastAPI endpoint?

Appels asynchrones avec HTTPX dans les points de terminaison FastAPI

Préoccupations concernant l'utilisation de ThreadPoolExecutor dans FastAPI

Vous a exprimé des inquiétudes quant à l'impact de l'utilisation de concurrent.futures.ThreadPoolExecutor dans un point de terminaison FastAPI, en particulier en ce qui concerne la création de threads, la famine de l'hôte et les plantages d'applications. Ces préoccupations sont valables car une création excessive de threads peut solliciter les ressources et potentiellement entraîner des problèmes de performances.

Recommandation : API HTTPX Async

Pour éviter ces pièges potentiels, il est recommandé de utilisez les capacités asynchrones de la bibliothèque HTTPX au lieu de concurrent.futures.ThreadPoolExecutor. HTTPX fournit une API asynchrone efficace qui vous permet d'effectuer des requêtes HTTP sans avoir besoin d'une gestion explicite des threads. Cette approche offre plusieurs avantages :

  • Regroupement de connexions contrôlé : HTTPX vous permet de contrôler la taille du pool de connexions, garantissant qu'un nombre raisonnable de connexions est maintenu pour des performances optimales sans submerger l'hôte.
  • Requêtes asynchrones : Les requêtes asynchrones ne bloquent pas la boucle d'événements, libérant des ressources pour d'autres opérations, évitant ainsi les goulots d'étranglement des performances.
  • Arrêt gracieux : HTTPX vous permet de fermer explicitement l'instance AsyncClient, garantissant ainsi un nettoyage approprié et empêchant les fuites de ressources.

Exemple de travail

Le code suivant L'extrait montre comment implémenter des requêtes HTTP asynchrones avec HTTPX dans un point de terminaison FastAPI :

from fastapi import FastAPI, Request
from contextlib import asynccontextmanager
import httpx
import asyncio

URLS = ['https://www.foxnews.com/',
        'https://edition.cnn.com/',
        'https://www.nbcnews.com/',
        'https://www.bbc.co.uk/',
        'https://www.reuters.com/']

@asynccontextmanager
async def lifespan(app: FastAPI):
    # customise settings
    limits = httpx.Limits(max_keepalive_connections=5, max_connections=10)
    timeout = httpx.Timeout(5.0, read=15.0)  # 15s timeout on read. 5s timeout elsewhere.

    # Initialise the Client on startup and add it to the state
    async with httpx.AsyncClient(limits=limits, timeout=timeout) as client:
        yield {'client': client}
        # The Client closes on shutdown 

app = FastAPI(lifespan=lifespan)

async def send(url, client):
    return await client.get(url)

@app.get('/')
async def main(request: Request):
    client = request.state.client
    tasks = [send(url, client) for url in URLS]
    responses = await asyncio.gather(*tasks)
    return [r.text[:50] for r in responses]  # for demo purposes, only return the first 50 chars of each response
Copier après la connexion

Alternative : diffuser des réponses en continu pour éviter l'utilisation de la RAM

Si vous lisez l'intégralité du corps de la réponse dans la RAM est un problème, envisagez d'utiliser les réponses Streaming de HTTPX avec StreamingResponse de FastAPI :

... # (same as previous code snippet)

async def iter_content(responses):
     for r in responses:
        async for chunk in r.aiter_text():
            yield chunk[:50]  # for demo purposes, return only the first 50 chars of each response and then break the loop
            yield '\n\n'
            break
        await r.aclose()

@app.get('/')
async def main(request: Request):
    client = request.state.client
    tasks = [send(url, client) for url in URLS]
    responses = await asyncio.gather(*tasks)
    return StreamingResponse(iter_content(responses), media_type='text/event-stream')
Copier après la connexion

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

source:php.cn
Déclaration de ce site Web
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn
Derniers articles par auteur
Tutoriels populaires
Plus>
Derniers téléchargements
Plus>
effets Web
Code source du site Web
Matériel du site Web
Modèle frontal