Profilowanie użycia pamięci aplikacji w języku Python w usłudze Azure Functions
Podczas programowania lub po wdrożeniu lokalnego projektu aplikacji funkcji języka Python na platformie Azure warto przeanalizować potencjalne wąskie gardła pamięci w funkcjach. Takie wąskie gardła mogą zmniejszyć wydajność funkcji i prowadzić do błędów. Poniższe instrukcje pokazują, jak używać pakietu języka Python profilera pamięci, który zapewnia analizę zużycia pamięci po wierszu funkcji podczas ich wykonywania.
Uwaga
Profilowanie pamięci jest przeznaczone tylko do analizy śladu pamięci w środowiskach deweloperskich. Nie należy stosować profilera pamięci w aplikacjach funkcji produkcyjnych.
Wymagania wstępne
Przed rozpoczęciem tworzenia aplikacji funkcji języka Python należy spełnić następujące wymagania:
Środowisko Python w wersji 3.7 lub nowszej. Aby sprawdzić pełną listę obsługiwanych wersji języka Python w usłudze Azure Functions, zobacz Przewodnik dla deweloperów języka Python.
Narzędzia Azure Functions Core Tools w wersji 4.x lub nowszej. Sprawdź wersję za pomocą polecenia
func --version
. Aby dowiedzieć się więcej na temat aktualizowania, zobacz Azure Functions Core Tools w witrynie GitHub.Program Visual Studio Code zainstalowany na jednej z obsługiwanych platform.
Aktywna subskrypcja platformy Azure.
Jeśli nie masz subskrypcji platformy Azure, przed rozpoczęciem utwórz bezpłatne konto platformy Azure.
Proces profilowania pamięci
W requirements.txt dodaj,
memory-profiler
aby upewnić się, że pakiet jest powiązany z wdrożeniem. Jeśli programujesz na komputerze lokalnym, możesz aktywować środowisko wirtualne języka Python i wykonać rozwiązanie pakietu przezpip install -r requirements.txt
polecenie .W skrywcie funkcji (na przykład __init__.py dla modelu programowania Python w wersji 1 i function_app.py dla modelu w wersji 2 dodaj następujące wiersze powyżej
main()
funkcji. Te wiersze zapewniają, że główny rejestrator raportuje nazwy podrzędnego rejestratora, aby dzienniki profilowania pamięci były rozróżniane przez prefiksmemory_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)
Zastosuj następujący dekorator powyżej wszystkich funkcji wymagających profilowania pamięci. Dekorator nie działa bezpośrednio w metodzie punktu wejścia
main()
wyzwalacza. Musisz utworzyć funkcje podrzędne i udekorować je. Ponadto ze względu na znany problem z profilerem pamięci podczas stosowania do asynchronicznego coroutine wartość zwracana jest zawszeNone
.@memory_profiler.profile(stream=profiler_logstream)
Przetestuj profiler pamięci na komputerze lokalnym przy użyciu polecenia
func host start
Azure Functions Core Tools . Podczas wywoływania funkcji powinny one generować raport użycia pamięci. Raport zawiera nazwę pliku, wiersz kodu, użycie pamięci, przyrost pamięci i zawartość wiersza w nim.Aby sprawdzić dzienniki profilowania pamięci w istniejącym wystąpieniu aplikacji funkcji na platformie Azure, możesz wykonać zapytanie dotyczące dzienników profilowania pamięci pod kątem ostatnich wywołań za pomocą zapytań Kusto w usłudze Application Insights, logs.
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
Przykład
Oto przykład wykonywania profilowania pamięci na asynchronicznym i synchronicznym wyzwalaczu HTTP o nazwach "HttpTriggerAsync" i "HttpTriggerSync". Utworzymy aplikację funkcji języka Python, która po prostu wysyła żądania GET na stronę główną firmy Microsoft.
Tworzenie aplikacji funkcji języka Python
Aplikacja funkcji języka Python powinna być zgodna z określoną strukturą folderów usługi Azure Functions. W celu tworzenia szkieletu projektu zalecamy użycie narzędzi Azure Functions Core Tools, uruchamiając następujące polecenia:
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
Aktualizowanie zawartości pliku
Requirements.txt definiuje pakiety używane w naszym projekcie. Oprócz zestawu SDK usługi Azure Functions i profilera pamięci wprowadzamy aiohttp
obsługę asynchronicznych żądań HTTP i requests
synchronicznych wywołań HTTP.
# requirements.txt
azure-functions
memory-profiler
aiohttp
requests
Utwórz asynchroniczny wyzwalacz HTTP.
Zastąp kod w asynchronicznym wyzwalaczu HTTP HttpTriggerAsync/__init__.py następującym kodem, który konfiguruje profiler pamięci, format głównego rejestratora i powiązanie przesyłania strumieniowego rejestratora.
# 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
Utwórz synchroniczny wyzwalacz HTTP.
Zastąp kod w asynchronicznym wyzwalaczu HTTP HttpTriggerSync/__init__.py następującym kodem.
# 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
Profilowanie aplikacji funkcji języka Python w lokalnym środowisku projektowym
Po wprowadzeniu powyższych zmian istnieje jeszcze kilka kroków inicjowania środowiska wirtualnego języka Python dla środowiska uruchomieniowego usługi Azure Functions.
Otwórz program Windows PowerShell lub dowolną powłokę systemu Linux w preferowany sposób.
Utwórz środowisko wirtualne języka Python według
py -m venv .venv
w systemie Windows lubpython3 -m venv .venv
w systemie Linux.Aktywuj środowisko wirtualne języka Python za pomocą
.venv\Scripts\Activate.ps1
programu Windows PowerShell lubsource .venv/bin/activate
powłoki systemu Linux.Przywracanie zależności języka Python za pomocą polecenia
pip install -r requirements.txt
Lokalne uruchamianie środowiska uruchomieniowego usługi Azure Functions przy użyciu narzędzi Azure Functions Core Tools
func host start
Wyślij żądanie GET do
https://localhost:7071/api/HttpTriggerAsync
lubhttps://localhost:7071/api/HttpTriggerSync
.Powinien zostać wyświetlony raport profilowania pamięci podobny do poniższej sekcji w narzędziach 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()
Następne kroki
Aby uzyskać więcej informacji na temat programowania w języku Python w usłudze Azure Functions, zobacz następujące zasoby: