Erstellen eines Profils der Arbeitsspeichernutzung für Python-Apps in Azure Functions
Bei der Entwicklung oder nach der Bereitstellung Ihres lokalen Python-Funktions-App-Projekts in Azure sollten Sie analysieren, ob Ihre Funktionen potenzielle Arbeitsspeicherengpässe aufweisen. Solche Engpässe können die Leistung Ihrer Funktionen beeinträchtigen und zu Fehlern führen. Die folgenden Anweisungen zeigen Ihnen, wie Sie das Python-Paket memory-profiler verwenden, das den Speicherverbrauch Ihrer Funktionen während der Ausführung Zeile für Zeile analysiert.
Hinweis
Die Speicherprofilerstellung ist nur für die Analyse des Speicherbedarfs in Entwicklungsumgebungen vorgesehen. Wenden Sie den Arbeitsspeicherprofiler nicht auf Produktionsfunktions-Apps an.
Voraussetzungen
Bevor Sie mit der Entwicklung einer Python-Funktions-App beginnen, müssen Sie die folgenden Anforderungen erfüllen:
Python 3.7 oder höher. Die vollständige Liste der unterstützten Python-Versionen in Azure Functions finden Sie im Python-Entwicklerhandbuch.
Azure Functions Core Tools, Version 4.x oder höher. Überprüfen Sie Ihre Version mit
func --version
. Weitere Informationen zum Aktualisieren finden Sie unter Azure Functions Core Tools auf GitHub.Visual Studio Code auf einer der unterstützten Plattformen installiert.
Ein aktives Azure-Abonnement.
Sollten Sie über kein Azure-Abonnement verfügen, können Sie zunächst ein kostenloses Azure-Konto erstellen.
Der Prozess der Arbeitsspeicher-Profilerstellung
Fügen Sie in Ihrer Datei „requirements.txt“
memory-profiler
hinzu, um sicherzustellen, dass das Paket mit Ihrer Bereitstellung gebündelt wird. Wenn Sie die Entwicklung auf dem lokalen Computer vornehmen, könnten Sie eine virtuelle Python-Umgebung aktivieren und eine Paketauflösung mitpip install -r requirements.txt
durchführen.Fügen Sie in Ihrem Funktionsskript (z. B. __init__.py für das Python v1-Programmiermodell und function_app.py für das v2-Modell) die folgenden Zeilen über der Funktion
main()
hinzu. Durch diese Zeilen wird sichergestellt, dass die Stammprotokollierung die Namen der untergeordneten Protokollierung meldet, damit die Protokolle der Speicherprofilerstellung durch das Präfixmemory_profiler_logs
unterschieden werden können.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)
Wenden Sie den folgenden Decorator über allen Funktionen an, für die eine Speicherprofilierung erforderlich ist. Dieser Decorator funktioniert nicht direkt über die Trigger-Einstiegspunktmethode
main()
. Sie müssen hierzu Unterfunktionen mit einem Decorator erstellen. Auch ist der Rückgabewert der Coroutine beim Anwenden auf eine asynchrone Coroutine aufgrund eines bekannten Problems bei der Speicherprofilerstellung immerNone
.@memory_profiler.profile(stream=profiler_logstream)
Überprüfen Sie die Speicherprofilerstellung auf Ihrem lokalen Computer mithilfe des Azure Functions Core Tools-Befehls
func host start
. Wenn Sie die Funktionen aufrufen, sollten sie einen Bericht zur Speicherauslastung generieren. Der Bericht enthält Dateiname, Codezeile, Speicherauslastung, Speicherinkrement und den darin enthaltenen Zeileninhalt.Die Protokolle der Speicherprofilerstellung der letzten Aufrufe einer vorhandenen Funktions-App-Instanz können Sie in Azure mit den folgenden Kusto-Abfragen in Application Insights (Protokolle) überprüfen.
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
Beispiel
Hier ist ein Beispiel für die Durchführung der Speicherprofilerstellung auf einem asynchronen und einem synchronen HTTP-Trigger mit den Namen „HttpTriggerAsync“ und „HttpTriggerSync“. Wir erstellen eine Python-Funktions-App, die einfach GET-Anforderungen an die Homepage von Microsoft sendet.
Erstellen einer Python-Funktions-App
Eine Python-Funktions-App sollte die von Azure Functions vorgegebene Ordnerstruktur berücksichtigen. Sie sollten Azure Functions Core Tools als Gerüst des Projekts verwenden, indem Sie die folgenden Befehle ausführen:
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
Aktualisieren des Dateiinhalts
Die Datei requirements.txt definiert die Pakete, die in unserem Projekt verwendet werden. Neben dem Azure Functions SDK und dem Arbeitsspeicherprofiler werden aiohttp
für asynchrone HTTP-Anforderungen und requests
für synchrone HTTP-Aufrufe eingeführt.
# requirements.txt
azure-functions
memory-profiler
aiohttp
requests
Erstellen Sie den asynchronen HTTP-Trigger.
Ersetzen Sie den Code im asynchronen HTTP-Trigger HttpTriggerAsync/__init__.py durch den folgenden Code, der die Speicherprofilerstellung, das Stammprotokollierungsformat und die Protokollierungsstreamingbindung konfiguriert.
# 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
Erstellen Sie den synchronen HTTP-Trigger.
Ersetzen Sie den Code im asynchronen HTTP-Trigger HttpTriggerSync/__init__.py durch den folgenden 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
Profilerstellung für Python-Funktions-Apps in lokaler Entwicklungsumgebung
Nachdem Sie alle oben genannten Änderungen vorgenommen haben, sind einige weitere Schritte erforderlich, um eine virtuelle Python-Umgebung für die Azure Functions-Runtime zu initialisieren.
Öffnen Sie nach Wunsch eine Windows PowerShell-Instanz oder eine beliebige Linux-Shell.
Erstellen Sie eine virtuelle Python-Umgebung mit
py -m venv .venv
unter Windows oderpython3 -m venv .venv
unter Linux.Aktivieren Sie die virtuelle Python-Umgebung mit
.venv\Scripts\Activate.ps1
in Windows PowerShell oder mitsource .venv/bin/activate
in der Linux-Shell.Wiederherstellen der Python-Abhängigkeiten mit
pip install -r requirements.txt
Starten Sie die Azure Functions-Runtime lokal mit
func host start
Azure Functions Core Tools.Senden Sie eine GET-Anforderung an
https://localhost:7071/api/HttpTriggerAsync
oderhttps://localhost:7071/api/HttpTriggerSync
.Es sollte ein Bericht zur Speicherprofilerstellung angezeigt werden, der dem folgenden Abschnitt in Azure Functions Core Tools ähnelt.
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()
Nächste Schritte
Weitere Informationen zur Python-Entwicklung für Azure Functions finden Sie in den folgenden Ressourcen: