Delen via


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:

Als u geen Azure-abonnement hebt, kunt u een gratis Azure-account maken voordat u begint.

Proces voor geheugenprofilering

  1. 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

  2. Voeg in uw functiescript (bijvoorbeeld __init__.py voor het Python v1-programmeermodel en function_app.py voor het v2-model) de volgende regels boven de main() functie toe. Deze regels zorgen ervoor dat de hoofdlogger de namen van de onderliggende logboekregistratie rapporteert, zodat de logboeken voor geheugenprofilering kunnen worden onderscheiden door het voorvoegsel memory_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)
    
  3. 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 altijd None.

    @memory_profiler.profile(stream=profiler_logstream)
    
  4. Test de geheugenprofielfunctie op uw lokale computer met behulp van de opdracht func host startAzure 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.

  5. 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.

    Screenshot showing the query memory usage of a Python app in Application Insights.

    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
    

voorbeeld

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.

  1. Open een Windows PowerShell of een Linux-shell zoals u wilt.

  2. Maak een virtuele Python-omgeving in py -m venv .venv Windows of python3 -m venv .venv in Linux.

  3. Activeer de virtuele Python-omgeving met .venv\Scripts\Activate.ps1 In Windows PowerShell of source .venv/bin/activate in Linux Shell.

  4. De Python-afhankelijkheden herstellen met pip install -r requirements.txt

  5. De Azure Functions-runtime lokaal starten met Azure Functions Core Tools func host start

  6. Verzend een GET-aanvraag naar https://localhost:7071/api/HttpTriggerAsync of https://localhost:7071/api/HttpTriggerSync.

  7. 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: