Questa guida descrive le ottimizzazioni per i servizi Cloud Run scritte nel linguaggio di programmazione Python, insieme alle informazioni di base per comprendere i compromessi in alcune delle ottimizzazioni. Le informazioni contenute in questa pagina integrano i suggerimenti per l'ottimizzazione generale, validi anche per Python.
Molte delle best practice e delle ottimizzazioni in queste applicazioni tradizionali basate sul Web Python si basano su:
- Gestione delle richieste in parallelo (I/O sia thread che non bloccanti)
- Riduzione della latenza delle risposte utilizzando il pool di connessioni e le funzionalità batch non critiche, ad esempio l'invio di tracce e metriche alle attività in background.
Ottimizzare l'immagine container
Ottimizzando l'immagine container, puoi ridurre i tempi di caricamento e di avvio. Puoi ottimizzare l'immagine nei seguenti modi:
- Inserisci nel container solo ciò di cui la tua app ha bisogno per il runtime
- Ottimizzazione del server WSGI
Inserisci nel container solo ciò di cui la tua app ha bisogno per il runtime
Valuta quali componenti sono inclusi nel container e se sono richiesti per l'esecuzione del servizio. Esistono diversi modi per ridurre al minimo l'immagine del container:
- Utilizza un'immagine di base più piccola
- Spostare file di grandi dimensioni all'esterno del container
Utilizza un'immagine di base più piccola
Docker Hub fornisce una serie di immagini di base Python ufficiali che puoi utilizzare se scegli di non installare Python dall'origine all'interno dei tuoi container. che dipendono dal sistema operativo Debian.
Se utilizzi l'immagine python
di Docker Hub, valuta l'uso della versione slim
.
Queste immagini hanno dimensioni più piccole perché non sono dotate di una serie di pacchetti utilizzati per creare ruote, ad esempio che non è necessario utilizzare per l'applicazione. Ad esempio, l'immagine python viene fornita con il compilatore GNU C, il preprocessore e le utilità principali.
Per identificare i dieci pacchetti più grandi in un'immagine di base, puoi eseguire questo comando:
DOCKER_IMAGE=python # or python:slim
docker run --rm ${DOCKER_IMAGE} dpkg-query -Wf '${Installed-Size}\t${Package}\t${Description}\n' | sort -n | tail -n10 | column -t -s $'\t'
Poiché il numero di questi pacchetti di basso livello è inferiore, le immagini basate su slim
offrono anche una minore superficie di attacco per potenziali vulnerabilità. Queste immagini potrebbero non includere gli elementi necessari per creare le ruote dall'origine.
Puoi aggiungere di nuovo pacchetti specifici aggiungendo una riga RUN apt install
al tuo Dockerfile. Scopri di più sull'utilizzo dei pacchetti di sistema in Cloud Run.
Sono disponibili anche opzioni per i container non basati su Debian. L'opzione python:alpine
può comportare un container molto più piccolo, ma molti pacchetti Python potrebbero non avere ruote precompilate che supportano i sistemi basati su Alpi. L'assistenza migliora
(vedi PEP-656), ma continua a essere
variata. Puoi anche utilizzare distroless base image
, che non contiene gestori di pacchetti, shell o altri programmi.
Spostare file di grandi dimensioni all'esterno del container
I file di grandi dimensioni, come gli asset multimediali, ecc. non devono essere inclusi nel contenitore di base.
Google Cloud offre diverse opzioni di hosting, come Cloud Storage, per archiviare questi elementi di grandi dimensioni. Spostare asset di grandi dimensioni in questi servizi, quindi farvi riferimento dalla tua applicazione in fase di esecuzione.
Ottimizzare il server WSGI
Python ha standardizzato il modo in cui le applicazioni possono interagire con i server web mediante l'implementazione dello standard WSGI PEP-3333. Uno dei server WSGI più comuni è gunicorn
, utilizzato in gran parte della documentazione di esempio.
Ottimizza gunicorn
La parte CMD
di Dockerfile
mostra una chiamata ottimizzata di gunicorn
:
Se stai pensando di modificare queste impostazioni, regola il numero di worker e thread in base all'applicazione. Ad esempio, prova a utilizzare un numero di worker uguale ai core disponibili e assicurati che le prestazioni siano migliorate, quindi regola il numero di thread. L'impostazione di troppi worker o thread può avere un impatto negativo, ad esempio una latenza di avvio a freddo più lunga, una memoria più utilizzata, richieste più piccole al secondo e così via.
L'aggiunta dell'impostazione --preload
può aiutarti a:
- Identifica i bug gravi del runtime al momento del deployment
- Risparmia risorse di memoria
Prima di aggiungere questo componente, dovresti valutare cosa viene caricato preventivamente dalla tua applicazione.
Altri server WSGI
Non è consentito utilizzare gunicorn
per eseguire Python in container.
Puoi utilizzare qualsiasi server web WSGI o ASGI, purché il container rimanga in ascolto sulla porta HTTP $PORT
, in base al contratto di runtime dei container.
Le alternative più comuni includono uwsgi
,
uvicorn
e waitress
.
Ad esempio, se un file denominato main.py
contiene l'oggetto app
, le seguenti chiamate avvieranno un server WSGI:
# uwsgi: pip install pyuwsgi
uwsgi --http :$PORT -s /tmp/app.sock --manage-script-name --mount /app=main:app
# uvicorn: pip install uvicorn
uvicorn --port $PORT --host 0.0.0.0 main:app
# waitress: pip install waitress
waitress-serve --port $PORT main:app
Puoi aggiungerli come riga CMD exec
in Dockerfile
o come voce web:
in Procfile
quando utilizzi i buildpack di Google Cloud.
Ottimizza le applicazioni
Nel codice del servizio Cloud Run, puoi anche eseguire l'ottimizzazione per ridurre i tempi di avvio e l'utilizzo della memoria.
Ridurre i thread
Puoi ottimizzare la memoria riducendo il numero di thread, utilizzando strategie reattive non bloccanti ed evitando attività in background. Inoltre, evita di scrivere nel file system, come indicato nella pagina dei suggerimenti generali.
Se vuoi supportare le attività in background nel servizio Cloud Run, imposta la CPU del servizio Cloud Run in modo che sia sempre allocata in modo da poter eseguire le attività in background al di fuori delle richieste e mantenere comunque l'accesso alla CPU.
Riduci le attività di avvio
Le applicazioni basate su Web Python possono avere molte attività da completare durante l'avvio, ad esempio il precaricamento dei dati, il riscaldamento della cache, la creazione di pool di connessioni e così via. Queste attività, se eseguite in sequenza, possono essere lente. Tuttavia, se vuoi che vengano eseguite in parallelo, devi aumentare il numero di core CPU.
Attualmente Cloud Run invia una richiesta di utente reale per attivare un'istanza di avvio completo. Gli utenti che hanno assegnato una richiesta a un'istanza appena avviata potrebbero riscontrare ritardi lunghi. Cloud Run attualmente non ha un controllo di "idoneità" per evitare di inviare richieste ad applicazioni non pronte.
Passaggi successivi
Per altri suggerimenti, consulta