إشعار
يتطلب الوصول إلى هذه الصفحة تخويلاً. يمكنك محاولة تسجيل الدخول أو تغيير الدلائل.
يتطلب الوصول إلى هذه الصفحة تخويلاً. يمكنك محاولة تغيير الدلائل.
في هذا الدرس، تقوم بنشر تطبيق Python دالات Azure يستخدم Durable Functions لتنسيق تحليل ملفات النص المتوازي. يقوم تطبيق الوظائف الخاص بك بتركيب مشاركة ملفات Azure، ويحلل عدة ملفات نصية بالتوازي (المعرض)، ويجمع النتائج (المروحة الداخلة)، ويعيدها إلى المتصل. يظهر هذا النهج ميزة رئيسية لتركيبات التخزين: الوصول المشترك للملفات عبر عدة نسخ وظيفية دون عبء شبكة لكل طلب.
في هذا البرنامج التعليمي، سوف تتعلّم:
- استخدم Azure Developer CLI لنشر تطبيق Durable Functions في خطة استهلاك مرنة مع مشاركة ملفات Azure مركبة
- تفعيل تنسيق لمعالجة ملفات نصية نموذجية بالتوازي
- تحقق من نتائج التحليل المجمعة
ملاحظة
عينات الكود لهذه المقالة متوفرة في مستودع Azure Functions Flex Consumption مع ملفات Azure OS Mount Samples Samples مستودع GitHub.
المتطلبات المسبقه
- حساب Azure مع اشتراك نشط. أنشئ حساباً مجاناً.
- Azure Developer CLI (azd) version 1.9.0 أو لاحقا
- بوابه
أمثلة واجهة السطر في هذا الدرس تستخدم بناء جملة Bash وقد تم اختبارها في أجهزة Azure Cloud Shell (Bash) وطرفيات لينكس/ماك أو إس.
تهيئة مشروع العينة
يمكنك العثور على نموذج الكود لهذا الدرس في مستودع Azure Functions Flex Consumption مع ملفات Azure OS Mount Samples Samples Repository على GitHub. يحتوي المجلد durable-text-analysis على كود تطبيق الوظيفة، وقالب Bicep الذي يوفر الموارد المطلوبة لأزور، وسكريبت بعد النشر يرفع ملفات نصية نموذجية.
افتح طرفية واذهب إلى الدليل الذي تريد استنساخ المستودع فيه.
استنساخ المستودع:
git clone https://github.com/Azure-Samples/Azure-Functions-Flex-Consumption-with-Azure-Files-OS-Mount-Samples.gitاذهب إلى مجلد المشروع:
cd Azure-Functions-Flex-Consumption-with-Azure-Files-OS-Mount-Samples/durable-text-analysisقم بتهيئة
azdالبيئة. عند طلب ذلك، أدخل اسم البيئة مثلdurable-text:azd init
مراجعة الرمز
الأجزاء الثلاثة الرئيسية التي تجعل هذه العينة تعمل هي البنية التحتية التي تنشئ التركيب، والنص الذي يرفع ملفات العينة، وكود الدالة الذي ينظم التحليل.
عند وقت التشغيل، تتبع التوزيع الموسيقي هذا التدفق:
- يبدأ منشور HTTP إلى
/api/start-analysisتوزيع Durable Functions. - يقوم المنسق باستدعاء
list_text_filesالنشاط للعثور على جميع.txtالملفات على التركيب. - يتفرق المنسق، ينادي
analyse_text_fileعلى كل ملف بالتوازي. - بمجرد الانتهاء من جميع المهام المتوازية، يقوم المنسق بدمج
aggregate_resultsالمقاييس لكل ملف في ملخص واحد. - يتم إرجاع النتيجة المجمعة كمخرج الأوركسترا.
تقوم الوحدة mounts.bicep بتكوين تركيب ملفات Azure SMB على تطبيق الوظائف. تحدد القيمة mountPath المسار المحلي الذي تظهر فيه الملفات أثناء وقت التشغيل. تمرر مفتاح الوصول إلى حساب التخزين كمعلمة، وتقوم المنصة بحلها أثناء التشغيل من خلال مرجع لخزنة المفاتيح:
@description('Function app name')
param functionAppName string
@description('Storage account name')
param storageAccountName string
@description('Storage account access key or app setting reference for Azure Files SMB mount')
param accessKey string
@description('Array of mount configurations')
param mounts array
// Function app reference
resource functionApp 'Microsoft.Web/sites@2023-12-01' existing = {
name: functionAppName
}
// Azure Files OS mount configuration
// Deploys azureStorageAccounts site config with all mounts in one shot
resource mountConfig 'Microsoft.Web/sites/config@2023-12-01' = {
parent: functionApp
name: 'azurestorageaccounts'
properties: reduce(mounts, {}, (cur, mount) => union(cur, {
'${mount.name}': {
type: 'AzureFiles'
shareName: mount.shareName
mountPath: mount.mountPath
accountName: storageAccountName
accessKey: accessKey
}
}))
}
output mountPaths array = [for mount in mounts: mount.mountPath]
نظرا لأن تركيبات ملفات Azure SMB لا تدعم بعد إدارة التحقق من هويتها، تحتاج إلى مفتاح حساب تخزين. كأفضل ممارسة، قم بتخزين هذا المفتاح في Azure Key Vault واستخدم مرجع Key Vault في إعداد التطبيق. إعداد التثبيت يشير إلى إعداد التطبيق باستخدام @AppSettingRef()، لذا لا يظهر المفتاح أبدا في قوالب العضلة ذات الرأس. تقوم الوحدة keyvault.bicep بإنشاء القبو، وتخزين المفتاح، وتمنح أدوار RBAC:
@description('Key Vault name')
param name string
@description('Location')
param location string
@description('Tags')
param tags object = {}
@description('Storage account name')
param storageAccountName string
@description('Principal ID of the function app identity (receives Key Vault Secrets User role)')
param functionAppPrincipalId string
@description('Principal ID of the deploying user (receives Key Vault Secrets Officer role)')
param deployerPrincipalId string = ''
// Storage account reference
resource storage 'Microsoft.Storage/storageAccounts@2023-05-01' existing = {
name: storageAccountName
}
// Key Vault with RBAC authorization
resource keyVault 'Microsoft.KeyVault/vaults@2023-07-01' = {
name: name
location: location
tags: tags
properties: {
sku: {
family: 'A'
name: 'standard'
}
tenantId: tenant().tenantId
enableRbacAuthorization: true
enabledForTemplateDeployment: true
enableSoftDelete: true
softDeleteRetentionInDays: 7
}
}
// Store storage account key as a secret (Azure Files mounts require shared key)
resource storageKeySecret 'Microsoft.KeyVault/vaults/secrets@2023-07-01' = {
parent: keyVault
name: 'storageAccountKey'
properties: {
value: storage.listKeys().keys[0].value
contentType: 'Storage account access key for Azure Files SMB mount'
}
}
// Built-in Key Vault RBAC role IDs
var roles = {
KeyVaultSecretsOfficer: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', 'b86a8fe4-44ce-4948-aee5-eccb2c155cd7')
KeyVaultSecretsUser: subscriptionResourceId('Microsoft.Authorization/roleDefinitions', '4633458b-17de-408a-b874-0445c86b69e6')
}
// Grant the function app identity read access to secrets
resource functionAppSecretsUser 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name: guid(keyVault.id, functionAppPrincipalId, roles.KeyVaultSecretsUser)
scope: keyVault
properties: {
roleDefinitionId: roles.KeyVaultSecretsUser
principalId: functionAppPrincipalId
principalType: 'ServicePrincipal'
}
}
// Grant the deployer manage access to secrets
resource deployerSecretsOfficer 'Microsoft.Authorization/roleAssignments@2022-04-01' = if (!empty(deployerPrincipalId)) {
name: guid(keyVault.id, deployerPrincipalId, roles.KeyVaultSecretsOfficer)
scope: keyVault
properties: {
roleDefinitionId: roles.KeyVaultSecretsOfficer
principalId: deployerPrincipalId
principalType: 'User'
}
}
output name string = keyVault.name
output uri string = keyVault.properties.vaultUri
output storageKeySecretUri string = storageKeySecret.properties.secretUri
يستدعي الملف main.bicep وحدات التثبيت وKey Vault:
// Key Vault for secure storage of Azure Files access key
module keyVault './app/keyvault.bicep' = {
name: 'keyVault'
scope: rg
params: {
name: !empty(keyVaultName) ? keyVaultName : '${abbrs.keyVaultVaults}${resourceToken}'
location: location
tags: tags
storageAccountName: storage.outputs.name
functionAppPrincipalId: processorIdentity.outputs.principalId
deployerPrincipalId: principalId
}
}
// Azure Files mount configuration (access key resolved via Key Vault reference)
module azureFilesMount './app/mounts.bicep' = {
name: 'azureFilesMount'
scope: rg
params: {
functionAppName: functionApp.outputs.name
storageAccountName: storage.outputs.name
accessKey: '@AppSettingRef(MOUNT_SECRET_REFERENCE)'
mounts: [
{
name: 'data'
shareName: 'data'
mountPath: '/mounts/data/'
}
]
}
dependsOn: [
functionAppRoleAssignments
]
النشر باستخدام Azure Developer CLI
هذه العينة هي قالب Azure Developer CLI (azd). بنية تحتية واحدة azd up لتوفير الأوامر، تنشر كود الوظيفة، وترفع ملفات نصية نموذجية إلى مشاركة ملفات Azure.
سجل الدخول إلى Azure. سكريبت ما بعد النشر يستخدم أوامر Azure CLI، لذا تحتاج إلى المصادقة باستخدام كلا الأداتين:
azd auth login az loginتوفير ونشر كل شيء:
azd upعند الطلب، اختر اشتراك Azure والموقع المناسب. ثم الأمر:
- ينشئ مجموعة موارد، حساب تخزين، خزنة مفاتيح، تطبيق دوال استهلاك مرن مع تكوين الوظائف المتينة، مثيل Application Insights وهوية مدارة
- ينشر كود دالة بايثون
- يرفع ملفات نصية نموذجية إلى مشاركة ملفات Azure
- يجري فحصا صحيا
ملاحظة
نظرا لأن تركيبات ملفات Azure SMB لا تدعم بعد إدارة التحقق من هويتها، تحتاج إلى مفتاح حساب تخزين. كأفضل ممارسة، يخزن النشر هذا المفتاح في Azure Key Vault ويستخدم مرجعا لخزنة المفاتيح حتى لا يتم كشف المفتاح أبدا في إعدادات التطبيق. يوفر هذا النهج إدارة مركزية للأسرار، والتدقيق، ودعم تدوير المفاتيح.
يستغرق النشر بضع دقائق. عند الانتهاء، ترى ملخصا للموارد التي تم إنشاؤها.
احفظ أسماء الموارد كمتغيرات shell للخطوات المتبقية:
RESOURCE_GROUP=$(azd env get-value AZURE_RESOURCE_GROUP) FUNCTION_APP_NAME=$(azd env get-value AZURE_FUNCTION_APP_NAME) FUNCTION_APP_URL=$(azd env get-value AZURE_FUNCTION_APP_URL)
تشغيل التوزيع الموسيقي
احصل على مفتاح المضيف الوظيفي:
HOST_KEY=$(az functionapp keys list \ --resource-group $RESOURCE_GROUP \ --name $FUNCTION_APP_NAME \ --query "functionKeys.default" \ -o tsv)ابدأ التوزيع الموسيقي. يمكنك اختياريا تمرير جسم JSON لتجاوز
{"mount_path": "/mounts/data/"}مسار التركيب الافتراضي:curl -s -X POST "${FUNCTION_APP_URL}/api/start-analysis?code=${HOST_KEY}" | jq .يتضمن الرد معرف المثيل وURIs إدارة يمكنك استخدامها للتحقق من الحالة، إرسال الأحداث، أو إنهاء التنسيق:
{ "id": "abc123def456", "statusQueryGetUri": "https://<your-app>.azurewebsites.net/...", "sendEventPostUri": "https://...", "terminatePostUri": "https://..." }
تحقق من النتائج
تحقق من حالة التوزيع باستخدام
statusQueryGetUriالاستجابة من المحفز:STATUS_URL="<statusQueryGetUri-from-trigger-response>" curl -s "${STATUS_URL}" | jq .أثناء تشغيل التوزيع الأوركسترالي، يكون
runtimeStatus.Runningعند الانتهاء، يبدو الرد كما يلي:{ "instanceId": "abc123def456", "runtimeStatus": "Completed", "output": { "total_files": 3, "total_words": 45, "total_lines": 12, "total_chars": 303, "overall_avg_word_length": 4.82, "overall_top_characters": [["e", 42], ["t", 38], ["a", 35]], "per_file": [ { "file_path": "/mounts/data/sample1.txt", "word_count": 15, "line_count": 4, "char_count": 98, "avg_word_length": 5.1, "top_characters": [["e", 14], ["t", 12]] }, { "file_path": "/mounts/data/sample2.txt", "word_count": 18, "line_count": 5, "char_count": 120, "avg_word_length": 4.6, "top_characters": [["a", 16], ["e", 15]] }, { "file_path": "/mounts/data/sample3.txt", "word_count": 12, "line_count": 3, "char_count": 85, "avg_word_length": 4.9, "top_characters": [["e", 13], ["t", 11]] } ] } }كما يعرض التطبيق نقطة نهاية مريحة عند
/api/status/{instance_id}تعيد استجابة حالة مبسطة.
نصيحة
تطبيق الوظائف الخاص بك يصل إلى الملفات الثلاثة بالتوازي عبر حامل التخزين. التطبيق لا يحتاج إلى مكالمات شبكية لكل طلب. تقرأ الوظيفة هذه البطاقات مباشرة من المشاركة المركبة باستخدام إدخال/إخراج الملفات القياسي. يظهر هذا النهج قوة قواعد التخزين مع الوظائف المتينة.
تنظيف الموارد
لتجنب الرسوم المستمرة، احذف جميع الموارد التي أنشأها هذا الدرس:
azd down --purge
تحذير
يقوم هذا الأمر بحذف مجموعة الموارد وجميع الموارد فيها، بما في ذلك تطبيق الدالة، وحساب التخزين، ونسخة Application Insights الخاصة بها.