دراسة استخدام ذاكرة تطبيقات Python في Azure Functions
في أثناء أو بعد تطوير مشروع تطبيق دالة Python المحلي إلى Azure، من الجيد تحليل اختناقات الذاكرة المحتملة في وظائفك. يمكن أن تقلل هذه الاختناقات من أداء وظائفك وتؤدي إلى أخطاء. توضح لك الإرشادات التالية كيفية استخدام حزمة Python لملف تعريف الذاكرة، والتي توفر تحليل استهلاك الذاكرة سطرا سطرا لوظائفك أثناء تنفيذها.
إشعار
جمع معلومات الذاكرة مخصص فقط لتحليل بصمة الذاكرة في بيئات التطوير. الرجاء عدم تطبيق محلل الذاكرة على تطبيقات وظيفة الإنتاج.
المتطلبات الأساسية
قبل البدء في تطوير تطبيق دالة Python، يجب أن تستوفي هذه المتطلبات:
Python 3.7 أو أعلى. للتحقق من القائمة الكاملة لإصدارات Python المدعومة في وظائف Azure، راجع Python developer guide.
Azure Functions Core Tools، الإصدار 4.x أو أحدث. تحقق من الإصدار الخاص بك باستخدام
func --version
. للتعرف على التحديث، راجع Azure Functions Core Tools على GitHub.يمكنك تثبيت Visual Studio Code على أحد الأنظمة الأساسية المدعومة.
اشتراك Azure نشط.
إذا لم يكن لديك اشتراك في Azure، فأنشئ حساب Azure مجاني قبل أن تبدأ.
عملية تحليل الذاكرة
في requirements.txt، أضف
memory-profiler
للتأكد من أن الحزمة مجمعة مع التوزيع الخاص بك. إذا كنت تقوم بالتطوير على جهازك المحلي، فقد تحتاج إلى تنشيط بيئة Python الظاهرية والقيام بحل الحزمة بواسطةpip install -r requirements.txt
.في البرنامج النصي للدالة (على سبيل المثال، __init__.py لنموذج برمجة Python v1 function_app.py لنموذج v2)، أضف الأسطر التالية أعلى الدالة
main()
. تضمن هذه الأسطر أن يقوم المسجل الجذر بالإبلاغ عن أسماء المسجل الفرعي، بحيث يمكن تمييز سجلات جمع معلومات الذاكرة بواسطة البادئة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)
قم بتطبيق المُحسِّن التالي فوق أي وظائف تحتاج إلى تحديد سمات الذاكرة. لا يعمل مصمم الديكور مباشرة على أسلوب نقطة
main()
إدخال المشغل. تحتاج إلى إنشاء وظائف فرعية وتزيينها. أيضا، بسبب مشكلة معروفة في محلل ملفات تعريف الذاكرة، عند تطبيقها على coroutine غير متزامن، تكون قيمة إرجاع coroutine دائماNone
.@memory_profiler.profile(stream=profiler_logstream)
اختبر محلل ملفات تعريف الذاكرة على جهازك المحلي باستخدام الأمر
func host start
Azure Functions Core Tools . عند استدعاء الدالات، يجب أن تنشئ تقرير استخدام الذاكرة. يحتوي التقرير على اسم الملف، سطر التعليمات البرمجية، استخدام الذاكرة، زيادة الذاكرة، ومحتوى السطر فيه.للتحقق من سجلات جمع معلومات الذاكرة على مثيل تطبيق دالة موجود في Azure، يمكنك الاستعلام عن سجلات جمع معلومات الذاكرة للاستدعاءات الأخيرة باستخدام استعلامات Kusto في 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
مثال
فيما يلي مثال على إجراء جمع معلومات الذاكرة على مشغل HTTP غير متزامن ومتزامن، يسمى "HttpTriggerAsync" و"HttpTriggerSync" على التوالي. سنقوم بإنشاء تطبيق وظائف Python الذي يرسل ببساطة طلبات GET إلى الصفحة الرئيسية ل Microsoft.
إنشاء تطبيق دالة Python
يجب أن يتبع تطبيق دالة Python بنية المجلد المحددة من قِبل Azure Functions إلى سقالات توليد المشاريع، نوصي باستخدام الأدوات الأساسية لـ Azure Functions عن طريق تشغيل الأوامر التالية:
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
تحديث محتويات الملف
يحدد requirements.txt الحزم المستخدمة في مشروعنا. بالإضافة إلى حزمة أدوات تطوير البرمجيات ومحلل ذاكرة Azure Functions، نقدم aiohttp
طلبات HTTP غير المتزامنة وrequests
مكالمات HTTP المتزامنة.
# requirements.txt
azure-functions
memory-profiler
aiohttp
requests
إنشاء مشغل HTTP غير المتزامن.
استبدل التعليمات البرمجية في مشغل HTTP غير المتزامن HttpTriggerAsync/__init__.py بالتعليمات البرمجية التالية، والتي تقوم بتكوين محلل ملفات تعريف الذاكرة وتنسيق مسجل الجذر وربط تدفق المسجل.
# 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
إنشاء مشغل HTTP المتزامن.
استبدل التعليمات البرمجية في مشغل HTTP غير المتزامن HttpTriggerSync/__init__.py بالتعليمات البرمجية التالية.
# 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 في بيئة التطوير المحلية
بعد إجراء التغييرات المذكورة أعلاه، هناك بضع خطوات أخرى لتهيئة بيئة Python الظاهرية لوقت تشغيل Azure Functions.
فتح Windows PowerShell أو أي Linux shell تفضل.
إنشاء بيئة افتراضية للـ Python عبر
py -m venv .venv
في Windows، أوpython3 -m venv .venv
في لينكس.تنشيط بيئة Python الظاهرية باستخدام
.venv\Scripts\Activate.ps1
في Windows PowerShell أوsource .venv/bin/activate
في Linux shell.استعادة تبعيات Python باستخدام
pip install -r requirements.txt
بدء وقت تشغيل Azure Functions محليًا باستخدام الأدوات الأساسية لـ Azure Functions
func host start
أرسل طلب GET إلى
https://localhost:7071/api/HttpTriggerAsync
أوhttps://localhost:7071/api/HttpTriggerSync
.يجب أن يظهر تقرير جمع معلومات الذاكرة مشابها للقسم التالي في 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()
الخطوات التالية
للحصول على مزيدٍ من المعلومات حول تطوير Python في وظائف Azure، راجع الموارد التالية: