Profilování využití paměti aplikací v Pythonu ve službě Azure Functions
Během vývoje nebo po nasazení místního projektu aplikace funkcí Pythonu do Azure je vhodné analyzovat potenciální kritické body paměti ve vašich funkcích. Takové kritické body můžou snížit výkon vašich funkcí a vést k chybám. Následující pokyny ukazují, jak používat balíček Pythonu profiler paměti, který poskytuje analýzu spotřeby paměti jednotlivých řádků vašich funkcí při jejich provádění.
Poznámka:
Profilace paměti je určená pouze pro analýzu stop paměti ve vývojových prostředích. Nepoužívejte profiler paměti v produkčních aplikacích funkcí.
Předpoklady
Než začnete vyvíjet aplikaci funkcí Pythonu, musíte splnit tyto požadavky:
Python 3.7 nebo vyšší Úplný seznam podporovaných verzí Pythonu ve službě Azure Functions najdete v příručce pro vývojáře Pythonu.
Nástroje Azure Functions Core Tools verze 4.x nebo vyšší. Zkontrolujte verzi pomocí
func --version
nástroje . Další informace o aktualizaci najdete v tématu Azure Functions Core Tools na GitHubu.Visual Studio Code nainstalovaný na jedné z podporovaných platforem.
Aktivní předplatné Azure.
Pokud ještě nemáte předplatné Azure, vytvořte si bezplatný účet Azure před tím, než začnete.
Proces profilace paměti
Do souboru requirements.txt přidejte
memory-profiler
, abyste zajistili, že je balíček součástí vašeho nasazení. Pokud vyvíjíte na místním počítači, možná budete chtít aktivovat virtuální prostředí Pythonu a provést překlad balíčku .pip install -r requirements.txt
Do skriptu funkce (například __init__.py pro programovací model Pythonu v1 a function_app.py pro model v2) přidejte nad funkci následující řádky
main()
. Tyto řádky zajišťují, že kořenový protokolovacíovač hlásí podřízené názvy protokolovacího nástroje, aby protokoly profilace paměti byly rozlišitelné předponoumemory_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)
Použijte následující dekorátor nad všemi funkcemi, které potřebují profilaci paměti. Dekorátor nefunguje přímo na metodě triggeru entrypointu
main()
. Potřebujete vytvořit dílčí funkce a ozdobit je. Také kvůli známému problému s profilerem paměti při použití asynchronní korutiny je návratová hodnota korutin vždyNone
.@memory_profiler.profile(stream=profiler_logstream)
Otestujte profiler paměti na místním počítači pomocí příkazu
func host start
Azure Functions Core Tools . Při vyvolání funkcí by měly vygenerovat sestavu využití paměti. Sestava obsahuje název souboru, řádek kódu, využití paměti, přírůstek paměti a obsah řádku.Pokud chcete zkontrolovat protokoly profilace paměti v existující instanci aplikace funkcí v Azure, můžete dotazovat protokoly profilace paměti na nedávné vyvolání pomocí dotazů Kusto v aplikaci Přehledy protokoly.
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
Příklad
Tady je příklad profilace paměti u asynchronního a synchronního triggeru HTTP s názvem HttpTriggerAsync a HttpTriggerSync. Vytvoříme aplikaci funkcí Pythonu, která jednoduše odešle požadavky GET na domovskou stránku Microsoftu.
Vytvoření aplikace funkcí Pythonu
Aplikace funkcí v Pythonu by měla dodržovat zadanou strukturu složek Azure Functions. Pokud chcete projekt vygenerovat, doporučujeme použít nástroje Azure Functions Core Tools spuštěním následujících příkazů:
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
Aktualizace obsahu souboru
Soubor requirements.txt definuje balíčky, které se používají v našem projektu. Kromě sady Azure Functions SDK a profileru paměti zavádíme aiohttp
asynchronní požadavky HTTP a requests
synchronní volání HTTP.
# requirements.txt
azure-functions
memory-profiler
aiohttp
requests
Vytvořte asynchronní trigger HTTP.
Nahraďte kód v asynchronním triggeru HTTP HttpTriggerAsync/__init__.py následujícím kódem, který konfiguruje profiler paměti, formát kořenového protokolovacího modulu a vazbu streamování protokolovacího modulu.
# 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
Vytvořte synchronní trigger HTTP.
Nahraďte kód v asynchronním triggeru HTTP HttpTriggerSync/__init__.py následujícím kódem.
# 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
Profilování aplikace funkcí Pythonu v místním vývojovém prostředí
Po provedení výše uvedených změn je několik dalších kroků pro inicializaci virtuálního prostředí Pythonu pro modul runtime Azure Functions.
Otevřete prostředí Windows PowerShell nebo libovolné linuxové prostředí podle potřeby.
Vytvořte virtuální prostředí Pythonu ve
py -m venv .venv
Windows nebopython3 -m venv .venv
v Linuxu.Aktivujte virtuální prostředí Pythonu v
.venv\Scripts\Activate.ps1
prostředí Windows PowerShell nebosource .venv/bin/activate
v linuxovém prostředí.Obnovení závislostí Pythonu pomocí
pip install -r requirements.txt
Místní spuštění modulu runtime Azure Functions pomocí nástrojů Azure Functions Core Tools
func host start
Odeslat požadavek GET do
https://localhost:7071/api/HttpTriggerAsync
nebohttps://localhost:7071/api/HttpTriggerSync
.V nástrojích Azure Functions Core Tools by se měla zobrazit sestava profilace paměti podobná následující části.
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()
Další kroky
Další informace o vývoji v Pythonu pro Azure Functions najdete v následujících zdrojích informací: