Profila l'utilizzo della memoria delle app Python in Funzioni di Azure
Durante lo sviluppo o dopo la distribuzione del progetto di app per le funzioni Python locale in Azure, è consigliabile analizzare i potenziali colli di bottiglia della memoria nelle funzioni. Tali colli di bottiglia possono ridurre le prestazioni delle funzioni e causare errori. Le istruzioni seguenti illustrano come usare il pacchetto Python memory-profiler , che fornisce l'analisi del consumo di memoria line-by-line delle funzioni durante l'esecuzione.
Nota
La profilatura della memoria è destinata solo all'analisi del footprint di memoria negli ambienti di sviluppo. Non applicare il profiler di memoria alle app per le funzioni di produzione.
Prerequisiti
Prima di iniziare a sviluppare un'app per le funzioni Python, è necessario soddisfare questi requisiti:
Python 3.7 o versione successiva. Per controllare l'elenco completo delle versioni di Python supportate in Funzioni di Azure, vedere la guida per sviluppatori Python.
Funzioni di Azure Core Tools, versione 4.x o successiva. Controllare la versione con
func --version
. Per informazioni sull'aggiornamento, vedere Funzioni di Azure Core Tools in GitHub.Visual Studio Code installato in una delle piattaforme supportate.
Una sottoscrizione di Azure attiva.
Se non si ha una sottoscrizione di Azure, creare un account Azure gratuito prima di iniziare.
Processo di profilatura della memoria
Nel file requirements.txt aggiungere
memory-profiler
per assicurarsi che il pacchetto sia incluso nella distribuzione. Se si sviluppa nel computer locale, è possibile attivare un ambiente virtuale Python ed eseguire una risoluzione del pacchetto tramitepip install -r requirements.txt
.Nello script della funzione (ad esempio, __init__.py per il modello di programmazione Python v1 e function_app.py per il modello v2), aggiungere le righe seguenti sopra la
main()
funzione. Queste righe assicurano che il logger radice restituisca i nomi dei logger figlio, in modo che i log di profilatura della memoria siano distinguibili dal prefissomemory_profiler_logs
.import logging import memory_profiler root_logger = logging.getLogger() root_logger.handlers[0].setFormatter(logging.Formatter("%(name)s: %(message)s")) profiler_logstream = memory_profiler.LogFile('memory_profiler_logs', True)
Applicare l'elemento Decorator seguente sopra tutte le funzioni che richiedono la profilatura della memoria. L'elemento Decorator non funziona direttamente sul metodo del punto
main()
di ingresso del trigger. È necessario creare sottofunzioni e decorarle. Inoltre, a causa di un problema noto di memory-profiler, quando si applica a una coroutine asincrona, il valore restituito della coroutine è sempreNone
.@memory_profiler.profile(stream=profiler_logstream)
Testare il profiler di memoria nel computer locale usando Funzioni di Azure comando
func host start
Core Tools . Quando si richiamano le funzioni, devono generare un report sull'utilizzo della memoria. Il report contiene il nome file, la riga di codice, l'utilizzo della memoria, l'incremento della memoria e il contenuto della riga.Per controllare i log di profilatura della memoria in un'istanza esistente dell'app per le funzioni in Azure, è possibile eseguire query sui log di profilatura della memoria per le chiamate recenti con query Kusto in Application Insights, Log.
traces | where timestamp > ago(1d) | where message startswith_cs "memory_profiler_logs:" | parse message with "memory_profiler_logs: " LineNumber " " TotalMem_MiB " " IncreMem_MiB " " Occurrences " " Contents | union ( traces | where timestamp > ago(1d) | where message startswith_cs "memory_profiler_logs: Filename: " | parse message with "memory_profiler_logs: Filename: " FileName | project timestamp, FileName, itemId ) | project timestamp, LineNumber=iff(FileName != "", FileName, LineNumber), TotalMem_MiB, IncreMem_MiB, Occurrences, Contents, RequestId=itemId | order by timestamp asc
Esempio
Ecco un esempio di esecuzione della profilatura della memoria in un trigger HTTP asincrono e sincrono, denominato rispettivamente "HttpTriggerAsync" e "HttpTriggerSync". Verrà compilata un'app per le funzioni Python che invia semplicemente richieste GET alla home page di Microsoft.
Creare un'app per le funzioni Python
Un'app per le funzioni Python deve seguire Funzioni di Azure struttura di cartelle specificata. Per eseguire lo scaffolding del progetto, è consigliabile usare Funzioni di Azure Core Tools eseguendo i comandi seguenti:
func init PythonMemoryProfilingDemo --python
cd PythonMemoryProfilingDemo
func new -l python -t HttpTrigger -n HttpTriggerAsync -a anonymous
func new -l python -t HttpTrigger -n HttpTriggerSync -a anonymous
Aggiornare il contenuto del file
Requirements.txt definisce i pacchetti usati nel progetto. Oltre a Funzioni di Azure SDK e memory-profiler, vengono introdotti aiohttp
per le richieste HTTP asincrone e requests
per le chiamate HTTP sincrone.
# requirements.txt
azure-functions
memory-profiler
aiohttp
requests
Creare il trigger HTTP asincrono.
Sostituire il codice nel trigger HTTP asincrono HttpTriggerAsync/__init__.py con il codice seguente, che configura il profiler di memoria, il formato del logger radice e l'associazione di streaming del logger.
# HttpTriggerAsync/__init__.py
import azure.functions as func
import aiohttp
import logging
import memory_profiler
# Update root logger's format to include the logger name. Ensure logs generated
# from memory profiler can be filtered by "memory_profiler_logs" prefix.
root_logger = logging.getLogger()
root_logger.handlers[0].setFormatter(logging.Formatter("%(name)s: %(message)s"))
profiler_logstream = memory_profiler.LogFile('memory_profiler_logs', True)
async def main(req: func.HttpRequest) -> func.HttpResponse:
await get_microsoft_page_async('https://microsoft.com')
return func.HttpResponse(
f"Microsoft page loaded.",
status_code=200
)
@memory_profiler.profile(stream=profiler_logstream)
async def get_microsoft_page_async(url: str):
async with aiohttp.ClientSession() as client:
async with client.get(url) as response:
await response.text()
# @memory_profiler.profile does not support return for coroutines.
# All returns become None in the parent functions.
# GitHub Issue: https://github.com/pythonprofilers/memory_profiler/issues/289
Creare il trigger HTTP sincrono.
Sostituire il codice nel trigger HTTP asincrono HttpTriggerSync/__init__.py con il codice seguente.
# HttpTriggerSync/__init__.py
import azure.functions as func
import requests
import logging
import memory_profiler
# Update root logger's format to include the logger name. Ensure logs generated
# from memory profiler can be filtered by "memory_profiler_logs" prefix.
root_logger = logging.getLogger()
root_logger.handlers[0].setFormatter(logging.Formatter("%(name)s: %(message)s"))
profiler_logstream = memory_profiler.LogFile('memory_profiler_logs', True)
def main(req: func.HttpRequest) -> func.HttpResponse:
content = profile_get_request('https://microsoft.com')
return func.HttpResponse(
f"Microsoft page response size: {len(content)}",
status_code=200
)
@memory_profiler.profile(stream=profiler_logstream)
def profile_get_request(url: str):
response = requests.get(url)
return response.content
Profilatura dell'app per le funzioni Python nell'ambiente di sviluppo locale
Dopo aver apportato le modifiche precedenti, è necessario eseguire altri passaggi per inizializzare un ambiente virtuale Python per Funzioni di Azure runtime.
Aprire una shell di Windows PowerShell o Linux come si preferisce.
Creare un ambiente virtuale Python in
py -m venv .venv
Windows opython3 -m venv .venv
in Linux.Attivare l'ambiente virtuale Python con
.venv\Scripts\Activate.ps1
in Windows PowerShell osource .venv/bin/activate
nella shell Linux.Ripristinare le dipendenze python con
pip install -r requirements.txt
Avviare il runtime di Funzioni di Azure in locale con Funzioni di Azure Core Tools
func host start
Inviare una richiesta GET a
https://localhost:7071/api/HttpTriggerAsync
ohttps://localhost:7071/api/HttpTriggerSync
.Dovrebbe essere visualizzato un report di profilatura della memoria simile alla sezione seguente in Funzioni di Azure Core Tools.
Filename: <ProjectRoot>\HttpTriggerAsync\__init__.py Line # Mem usage Increment Occurrences Line Contents ============================================================ 19 45.1 MiB 45.1 MiB 1 @memory_profiler.profile 20 async def get_microsoft_page_async(url: str): 21 45.1 MiB 0.0 MiB 1 async with aiohttp.ClientSession() as client: 22 46.6 MiB 1.5 MiB 10 async with client.get(url) as response: 23 47.6 MiB 1.0 MiB 4 await response.text()
Passaggi successivi
Per altre informazioni sullo sviluppo di Funzioni di Azure Python, vedere le risorse seguenti: