Azure İşlevleri'de Python uygulamalarının bellek kullanımının profilini oluşturma

Geliştirme sırasında veya yerel Python işlev uygulaması projenizi Azure'a dağıttığınızda işlevlerinizdeki olası bellek sorunlarını analiz etmek iyi bir uygulamadır. Bu tür performans sorunları işlevlerinizin performansını düşürebilir ve hatalara yol açabilir. Aşağıdaki yönergelerde, yürütülürken işlevlerinizin satır satır bellek tüketimi analizini sağlayan bellek profili oluşturucu Python paketinin nasıl kullanılacağı gösterilmektedir.

Dekont

Bellek profili oluşturma yalnızca geliştirme ortamlarında bellek ayak izi analizi için tasarlanmıştır. Lütfen bellek profil oluşturucuyu üretim işlevi uygulamalarına uygulamayın.

Ön koşullar

Python işlev uygulaması geliştirmeye başlamadan önce şu gereksinimleri karşılamanız gerekir:

Azure aboneliğiniz yoksa başlamadan önce birücretsiz Azure hesabı oluşturun.

Bellek profili oluşturma işlemi

  1. requirements.txt dosyasında paketin dağıtımınızla birlikte paketlendiğinden emin olmak için öğesini ekleyin memory-profiler . Yerel makinenizde geliştirme yapıyorsanız, bir Python sanal ortamını etkinleştirmek ve tarafından pip install -r requirements.txtbir paket çözümlemesi yapmak isteyebilirsiniz.

  2. İşlev betiğinizde (örneğin, Python v1 programlama modeli için __init__.py ve v2 modeli için function_app.py ) işlevin main() üzerine aşağıdaki satırları ekleyin. Bu satırlar kök günlükçü alt günlükçü adlarını bildirir, böylece bellek profili oluşturma günlükleri ön ek memory_profiler_logsile ayırt edilebilir.

    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. Bellek profili oluşturma gerektiren tüm işlevlerin üzerine aşağıdaki dekoratörü uygulayın. Dekoratör doğrudan tetikleyici giriş noktası main() yönteminde çalışmaz. Alt işlevleri oluşturmanız ve süslemeniz gerekir. Ayrıca, bellek profili oluşturucu bilinen bir sorun nedeniyle, zaman uyumsuz bir eş yordama uygulanırken, eş yordam dönüş değeri her zaman Noneşeklindedir.

    @memory_profiler.profile(stream=profiler_logstream)
    
  4. Azure İşlevleri Core Tools komutunu func host startkullanarak yerel makinenizde bellek profil oluşturucusunu test edin. İşlevleri çağırdığınızda, bir bellek kullanım raporu oluşturmaları gerekir. Rapor dosya adını, kod satırını, bellek kullanımını, bellek artışını ve içindeki satır içeriğini içerir.

  5. Azure'da mevcut bir işlev uygulaması örneğinde bellek profili oluşturma günlüklerini denetlemek için, Uygulama Analizler, Günlükler'de Kusto sorgularıyla yapılan son çağrılar için bellek profil oluşturma günlüklerini sorgulayabilirsiniz.

    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
    

Örnek

Burada sırasıyla "HttpTriggerAsync" ve "HttpTriggerSync" adlı zaman uyumsuz ve zaman uyumlu bir HTTP tetikleyicisinde bellek profili oluşturma işlemi gerçekleştirme örneği verilmiştir. Microsoft'un giriş sayfasına GET istekleri gönderen bir Python işlev uygulaması oluşturacağız.

Python işlev uygulaması oluşturma

Python işlev uygulaması belirtilen Azure İşlevleri klasör yapısını izlemelidir. Projenin iskelesini yapmak için aşağıdaki komutları çalıştırarak Azure İşlevleri Core Tools'u kullanmanızı öneririz:

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

Dosya içeriğini güncelleştirme

requirements.txt, projemizde kullanılan paketleri tanımlar. Azure İşlevleri SDK'sı ve bellek profili oluşturucunun yanı sıra, zaman uyumsuz HTTP istekleri ve requests zaman uyumlu HTTP çağrıları için tanıtıyoruzaiohttp.

# requirements.txt

azure-functions
memory-profiler
aiohttp
requests

Zaman uyumsuz HTTP tetikleyicisini oluşturun.

HttpTriggerAsync/__init__.py zaman uyumsuz HTTP tetikleyicisindeki kodu, bellek profil oluşturucu, kök günlükçü biçimi ve günlükçü akış bağlamasını yapılandıran aşağıdaki kodla değiştirin.

# 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

Zaman uyumlu HTTP tetikleyicisini oluşturun.

HttpTriggerSync/__init__.py zaman uyumsuz HTTP tetikleyicisindeki kodu aşağıdaki kodla değiştirin.

# 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

Yerel geliştirme ortamında Python işlev uygulamasının profilini oluşturma

Yukarıdaki değişiklikleri yaptıktan sonra, Azure İşlevleri çalışma zamanı için python sanal ortamını başlatmaya yönelik birkaç adım daha vardır.

  1. İstediğiniz gibi bir Windows PowerShell veya herhangi bir Linux kabuğu açın.

  2. Windows'da veya python3 -m venv .venv Linux'ta kullanarak py -m venv .venv bir Python sanal ortamı oluşturun.

  3. Windows PowerShell'de veya source .venv/bin/activate Linux kabuğunda ile .venv\Scripts\Activate.ps1 Python sanal ortamını etkinleştirin.

  4. ile Python bağımlılıklarını geri yükleme pip install -r requirements.txt

  5. Azure İşlevleri Core Araçları ile Azure İşlevleri çalışma zamanını yerel olarak başlatmafunc host start

  6. veya https://localhost:7071/api/HttpTriggerSyncöğesine https://localhost:7071/api/HttpTriggerAsync bir GET isteği gönderin.

  7. Azure İşlevleri Temel Araçları'nda aşağıdaki bölüme benzer bir bellek profili oluşturma raporu göstermelidir.

    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()
    

Sonraki adımlar

Python geliştirme Azure İşlevleri hakkında daha fazla bilgi için aşağıdaki kaynaklara bakın: