Geheugengebruik van Python-apps profilen in Azure Functions
Tijdens de ontwikkeling of na het implementeren van uw lokale Python-functie-app-project in Azure, is het een goede gewoonte om te analyseren op mogelijke knelpunten in het geheugen in uw functies. Dergelijke knelpunten kunnen de prestaties van uw functies verminderen en leiden tot fouten. In de volgende instructies ziet u hoe u het Python-pakket memory-profiler gebruikt, dat een analyse biedt van het gebruik van het line-by-line geheugen van uw functies tijdens de uitvoering.
Notitie
Geheugenprofilering is alleen bedoeld voor analyse van geheugenvoetafdruk in ontwikkelomgevingen. Pas de geheugenprofielfunctie niet toe op productiefunctie-apps.
Vereisten
Voordat u begint met het ontwikkelen van een Python-functie-app, moet u aan deze vereisten voldoen:
Python 3.7 of hoger. Raadpleeg de Ontwikkelaarshandleiding voor Python om de volledige lijst met ondersteunde Python-versies in Azure Functions te controleren.
De Azure Functions Core Tools, versie 4.x of hoger. Controleer uw versie met
func --version
. Zie Azure Functions Core Tools op GitHub voor meer informatie over het bijwerken.Visual Studio Code is geïnstalleerd op een van de ondersteunde platforms.
Een actief Azure-abonnement.
Als u geen Azure-abonnement hebt, kunt u een gratis Azure-account maken voordat u begint.
Proces voor geheugenprofilering
Voeg in uw requirements.txt toe
memory-profiler
om ervoor te zorgen dat het pakket is gebundeld met uw implementatie. Als u op uw lokale computer ontwikkelt, kunt u een virtuele Python-omgeving activeren en een pakketomzetting uitvoeren.pip install -r requirements.txt
Voeg in uw functiescript (bijvoorbeeld __init__.py voor het Python v1-programmeermodel en function_app.py voor het v2-model) de volgende regels toe boven de
main()
functie. Deze regels zorgen ervoor dat de hoofdlogger de namen van de onderliggende logboekregistratie rapporteert, zodat de logboeken voor geheugenprofilering kunnen worden onderscheiden door het voorvoegselmemory_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)
Pas de volgende decorator toe boven alle functies die geheugenprofilering nodig hebben. De decorator werkt niet rechtstreeks op de triggerinvoerpuntmethode
main()
. U moet subfuncties maken en ze versieren. Als gevolg van een bekend probleem met geheugenprofiel is de retourwaarde van coroutine bij het toepassen op een asynchrone coroutine altijdNone
.@memory_profiler.profile(stream=profiler_logstream)
Test de geheugenprofielfunctie op uw lokale computer met behulp van de opdracht
func host start
Azure Functions Core Tools. Wanneer u de functies aanroept, moeten ze een geheugengebruiksrapport genereren. Het rapport bevat bestandsnaam, regel code, geheugengebruik, geheugenverhoging en de regelinhoud hierin.Als u de logboeken voor geheugenprofilering wilt controleren op een bestaand exemplaar van een functie-app in Azure, kunt u query's uitvoeren op de logboeken voor geheugenprofilering voor recente aanroepen met Kusto-query's in Application Insights, Logboeken.
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
Opmerking
Hier volgt een voorbeeld van het uitvoeren van geheugenprofilering op een asynchrone en een synchrone HTTP-trigger, met de naam HttpTriggerAsync en HttpTriggerSync. We bouwen een Python-functie-app die eenvoudig GET-aanvragen verzendt naar de startpagina van Microsoft.
Een Python-functie-app maken
Een Python-functie-app moet de opgegeven mapstructuur van Azure Functions volgen. Als u het project wilt opzetten, raden we u aan de Azure Functions Core Tools te gebruiken door de volgende opdrachten uit te voeren:
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
Bestandsinhoud bijwerken
De requirements.txt definieert de pakketten die in ons project worden gebruikt. Naast de Azure Functions SDK en memory-profiler introduceren we aiohttp
asynchrone HTTP-aanvragen en requests
voor synchrone HTTP-aanroepen.
# requirements.txt
azure-functions
memory-profiler
aiohttp
requests
Maak de asynchrone HTTP-trigger.
Vervang de code in de asynchrone HTTP-trigger HttpTriggerAsync/__init__.py door de volgende code, waarmee de geheugenprofielfunctie, de indeling van de hoofdlogger en de streamingbinding voor logboekregistratie worden geconfigureerd.
# 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
Maak de synchrone HTTP-trigger.
Vervang de code in de asynchrone HTTP-trigger HttpTriggerSync/__init__.py door de volgende code.
# 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
Python-functie-app profilen in lokale ontwikkelomgeving
Nadat u de bovenstaande wijzigingen hebt aangebracht, zijn er nog enkele stappen voor het initialiseren van een virtuele Python-omgeving voor Azure Functions-runtime.
Open een Windows PowerShell of een Linux-shell zoals u wilt.
Maak een virtuele Python-omgeving in
py -m venv .venv
Windows ofpython3 -m venv .venv
in Linux.Activeer de virtuele Python-omgeving met
.venv\Scripts\Activate.ps1
In Windows PowerShell ofsource .venv/bin/activate
in Linux Shell.De Python-afhankelijkheden herstellen met
pip install -r requirements.txt
De Azure Functions-runtime lokaal starten met Azure Functions Core Tools
func host start
Verzend een GET-aanvraag naar
https://localhost:7071/api/HttpTriggerAsync
ofhttps://localhost:7071/api/HttpTriggerSync
.Er moet een geheugenprofileringsrapport worden weergegeven dat vergelijkbaar is met de volgende sectie in Azure Functions 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()
Volgende stappen
Zie de volgende resources voor meer informatie over het ontwikkelen van Azure Functions Python: