API Management
فما هي المشكلة التي أواجهها والتي تجعلني أرغب في البحث عن حل لإدارة واجهة برمجة التطبيقات؟ من المرجح أن تواجه التحديات التالية:
- التحجيم، يتم استخدام واجهة برمجة التطبيقات أو واجهات برمجة التطبيقات الخاصة بك من قبل العديد من العملاء في مناطق مختلفة من العالم وتحتاج إلى التأكد من أنها متاحة وسريعة الاستجابة.
- الأمان، تحتاج إلى التأكد من أن واجهة برمجة التطبيقات الخاصة بك آمنة وأن العملاء المعتمدين فقط يمكنهم الوصول إليها.
- إدارة الأخطاء، تحتاج إلى التأكد من أن واجهة برمجة التطبيقات الخاصة بك يمكنها معالجة الأخطاء بأمان.
- المراقبة، تحتاج إلى مراقبة واجهات برمجة التطبيقات للتأكد من أنها تعمل كما هو متوقع.
- المرونة، تحتاج إلى التأكد من أن واجهة برمجة التطبيقات الخاصة بك مرنة ويمكنها التعامل مع الإخفاقات بأمان.
لكل من هذه التحديات، يمكنك اختيار حل نقطة، ولكن قد يكون من الصعب إدارته. ضع في اعتبارك أيضا أنه يمكن إنشاء واجهات برمجة التطبيقات الخاصة بك في مكدسات تقنية مختلفة، ما يعني أن حلول التحديات المذكورة أعلاه قد تعني أنك بحاجة إلى حلول مختلفة لكل واجهة برمجة تطبيقات. إذا كنت تواجه جميع هذه التحديات، فيجب عليك التفكير في حل إدارة واجهة برمجة التطبيقات المركزي مثل Azure API Management.
دعونا نتعمق في بعض التحديات ونرى كيف يمكن أن يساعدك حل إدارة واجهة برمجة التطبيقات المركزي مثل Azure API Management في معالجتها.
البنية الأساسية كتعليق برمجي، IaC
إنه أمر جيد تماما عن طريق إنشاء موارد Azure باستخدام مدخل Microsoft Azure، ولكن مع نمو البنية الأساسية الخاصة بك، يصبح من الصعب إدارتها. إحدى المشاكل التي تواجهها هي أنه لا يمكنك بسهولة نسخ البنية الأساسية الخاصة بك في بيئة أخرى.
من الصعب أيضا تتبع جميع التغييرات التي يتم إجراؤها على البنية الأساسية الخاصة بك. هذا الموقف هو المكان الذي تأتي فيه البنية الأساسية كتعليق برمجي (IaC). IaC هي ممارسة إدارة البنية الأساسية الخاصة بك باستخدام التعليمات البرمجية. لتطبيق IaC على Azure، لديك العديد من الخيارات، أحدها Bicep. Bicep هي لغة خاصة بالمجال (DSL) لنشر موارد Azure بشكل تعريفي. إنها طريقة رائعة لإدارة موارد السحابة الخاصة بك. فيما يلي مثال بسيط لما يبدو عليه Bicep:
param location string = 'eastus'
resource storageAccount 'Microsoft.Storage/storageAccounts@2021-06-01' = {
name: 'mystorageaccount'
location: location
kind: 'StorageV2'
sku: {
name: 'Standard_LRS'
}
}
في المثال السابق، حددنا حساب تخزين باستخدام Bicep. لقد حددنا موقع حساب التخزين ونوع حساب التخزين وSKU (وحدة حفظ المخزون). الموقع هو معلمة يمكننا تمريرها عند نشر ملف Bicep. لنشر الملف المقدم، سنستخدم Azure CLI كما يلي:
az deployment group create --resource-group myResourceGroup --template-file main.bicep
يقوم الأمر السابق بنشر حساب التخزين إلى مجموعة myResourceGroup
الموارد واستخدام ملف main.bicep
Bicep لإنشاء الموارد في الملف.
معالجة التحميل عبر موازن التحميل
تعد إضافة بنية موازنة التحميل هي الحل عندما تكون المشكلة هي أن واجهة برمجة التطبيقات الخاصة بك غارقة في الطلبات. يمكن أن يساعدك موازن التحميل في توزيع الحمل عبر مثيلات متعددة من واجهة برمجة التطبيقات الخاصة بك.
في خدمة Azure API Management، يتم تنفيذ موازنة التحميل من خلال تحديد مفهوم يسمى الخلفيات. الفكرة هي أن تقوم بإعداد العديد من الواجهات الخلفية التي تتوافق مع نقاط نهاية واجهة برمجة التطبيقات الخاصة بك ثم تقوم بإنشاء موازن تحميل يوزع التحميل عبر هذه الواجهات الخلفية. إليك كيف تبدو البنية:
ما يحدث في البنية السابقة هو:
- يرسل العميل طلبا إلى مثيل APIM.
- الطلب مصادق عليه ومخول.
- ثم يتم إرسال الطلب إلى موازن التحميل.
- يوزع موازن التحميل الطلب على إحدى الخلفيات (يشار إلى واجهة برمجة تطبيقات Azure OpenAI المحددة بخط غامق).
تعالج الواجهة الخلفية الطلب وترسل استجابة مرة أخرى إلى العميل.
تعريف موازن التحميل
لإعداد موازن تحميل في Azure API Management، تحتاج إلى القيام بالأجزاء التالية:
- الخلفيات، أكبر عدد من الواجهات الخلفية التي تريد توزيع الحمل عليها.
- موازن التحميل، موازن تحميل يحتوي على الخلفيات التي تريد توزيع التحميل عبرها.
- نهج يوجه الاستدعاءات الواردة إلى موازن التحميل.
إنشاء الخلفيات
لإنشاء خلفية في Azure API Management، تحتاج إلى تعريف كيان الواجهة الخلفية. إليك كيفية تحديد خلفية في Bicep:
resource backend2 'Microsoft.ApiManagement/service/backends@2023-09-01-preview' = {
parent: apimService
name: 'backend2'
properties: {
url: '${openai2Endpoint}openai'
protocol: 'http'
circuitBreaker: {
rules: [
{
failureCondition: {
count: 3
errorReasons: [
'Server errors'
]
interval: 'P1D'
statusCodeRanges: [
{
min: 500
max: 599
}
]
}
name: 'myBreakerRule'
tripDuration: 'PT1H'
}
]
}
}
في تعليمة Bicep البرمجية السابقة، يتم تعريف خلفية لتتوافق مع عنوان URL لنقطة نهاية واجهة برمجة التطبيقات، لاحظ أيضا اسم backend2
هذا الاسم هو شيء يمكننا استخدامه لاحقا. لكل خلفية لديك، يجب عليك ترميزها مثل تعليمة bicep البرمجية السابقة.
إشعار
تذكر أنه يمكن أن يكون لديك واجهات خلفية متعددة، حتى تتمكن من تحديد العديد من الخلفيات كما تريد.
إنشاء تجمع الواجهة الخلفية
بعد ذلك، نريد إنشاء تجمع خلفية يقوم بإعداد الواجهات الخلفية التي نريد توزيع الحمل بينها. يمكننا ترميز تجمع الواجهة الخلفية هذا ككيان خلفي مثل ذلك:
resource loadBalancing 'Microsoft.ApiManagement/service/backends@2023-09-01-preview' = {
parent: apimService
name: 'LoadBalancer'
properties: {
description: 'Load balancer for multiple backends'
type: 'Pool'
pool: {
services: [
{
id: '/subscriptions/${subscriptionId}/resourceGroups/${resourceGroupName}/providers/Microsoft.ApiManagement/service/${apimService.name}/backends/${backend1.id}'
}
{
id: '/subscriptions/${subscriptionId}/resourceGroups/${resourceGroupName}/providers/Microsoft.ApiManagement/service/${apimService.name}/backends/${backend2.id}'
}
]
}
}
}
تتم الإشارة إلى الخلفية التي أنشأناها من قبل، backend2
، جنبا إلى جنب مع خلفية backend1
أخرى ، وهي الأخيرة التي حذفناها للإيجاز.
يمكننا أيضا تضمين priority
خاصية و weight
، لكل عنصر في services
القائمة لتحديد كيفية توزيع موازن التحميل للتحميل. إليك كيفية تعيين الأولوية والوزن لكل خلفية:
services: [
{
id: '/subscriptions/<subscriptionID>/resourceGroups/<resourceGroupName>/providers/Microsoft.ApiManagement/service/<APIManagementName>/backends/backend-1'
priority: 1
weight: 3
}
{
id: '/subscriptions/<subscriptionID>/resourceGroups/<resourceGroupName>/providers/Microsoft.ApiManagement/service/<APIManagementName>/backends/backend-2'
priority: 1
weight: 1
}
]
في المثال السابق، يوزع موازن التحميل الحمل على backend-1
ثلاثة أضعاف .backend-2
المكالمات الواردة المباشرة
وأخيرا، نحتاج إلى توجيه أي استدعاءات واردة إلى خلفية موازنة التحميل هذه. يتم إنشاء إرشادات الاتجاه كيان API التالي:
resource api1 'Microsoft.ApiManagement/service/apis@2020-06-01-preview' = {
parent: apimService
name: apiName
properties: {
displayName: apiName
apiType: 'http'
path: apiSuffix
format: 'openapi+json-link'
value: 'https://raw.githubusercontent.com/Azure/azure-rest-api-specs/main/specification/cognitiveservices/data-plane/AzureOpenAI/inference/preview/2024-03-01-preview/inference.json'
subscriptionKeyParameterNames: {
header: 'api-key'
}
}
تكوين النهج
الآن، أخيرا يمكننا تعيين النهج على واجهة برمجة التطبيقات الموضحة سابقا وتوجيه الاستدعاءات الواردة إلى موازن التحميل:
// policy.xml
<policies>
<inbound>
<base />
<set-backend-service id="apim-generated-policy" backend-id="{0}" />
</inbound>
<backend>
<base />
</backend>
<outbound>
<base />
</outbound>
<on-error>
<base />
</on-error>
</policies>
var headerPolicyXml = format(loadTextContent('./policy.xml'), loadBalancing.name, 5000)
// Create a policy for the API, using the headerPolicyXml variable
resource apiPolicy 'Microsoft.ApiManagement/service/apis/policies@2020-06-01-preview' = {
parent: api1
name: 'policy'
properties: {
format: 'rawxml'
value: headerPolicyXml
}
}
ما فعلناه هو إنشاء نهج يوجه المكالمات الواردة إلى موازن التحميل.
set-backend-service
يتم استخدام النهج لتوجيه المكالمات الواردة إلى موازن التحميل.
backend-id
يتم تعيين الخاصية إلى اسم موازن التحميل الذي أنشأناه من قبل.
مع وجود جميع هذه الأجزاء المتحركة في مكانها، يتم الآن تحميل مثيل APIM الخاص بك بشكل متوازن. يمكنك الآن توسيع نطاق واجهة برمجة التطبيقات الخاصة بك عن طريق إضافة المزيد من الخلفيات إلى موازن التحميل.
قاطع الدائرة
قاطع الدائرة هو شيء تستخدمه عندما تريد حماية واجهة برمجة التطبيقات الخاصة بك من أن تغمرها الطلبات. كيف يعمل هو أن تقوم بتعريف مجموعة من القواعد التي عند الوفاء بها، يقوم قاطع الدائرة بتشغيل وإيقاف إرسال الطلبات إلى الخلفية. في Azure API Management، يمكنك تعريف قاطع دائرة عن طريق إعداد خلفية وتعريف قاعدة قاطع الدائرة. إليك كيفية القيام بذلك:
resource backend2 'Microsoft.ApiManagement/service/backends@2023-09-01-preview' = {
parent: apimService
name: 'backend2'
properties: {
url: '${openai2Endpoint}openai'
protocol: 'http'
circuitBreaker: {
rules: [
{
failureCondition: {
count: 3
errorReasons: [
'Server errors'
]
interval: 'P1D'
statusCodeRanges: [
{
min: 500
max: 599
}
]
}
name: 'myBreakerRule'
tripDuration: 'PT1H'
}
]
}
}
}
في تعريف الخلفية السابق، هناك خاصية failureCondition
تحدد متى يجب أن يرحل قاطع الدائرة. في هذه الحالة، يقوم قاطع الدائرة بالرحلات إذا كان هناك ثلاثة أخطاء في الخادم في يوم واحد.
tripDuration
تحدد الخاصية المدة التي يجب أن يبقى فيها قاطع الدائرة مفتوحا قبل إغلاقه مرة أخرى. من الممارسات الجيدة تحديد قاطع دائرة لكل خلفية لديك في مثيل APIM.
الهوية المُدارة
هناك مشكلة أخرى نتطلع إلى معالجتها وهي الأمن. تريد التأكد من أن واجهة برمجة التطبيقات الخاصة بك آمنة وأن العملاء المعتمدين فقط يمكنهم الوصول إليها. طريقة لتأمين واجهة برمجة التطبيقات الخاصة بك هي باستخدام الهوية المدارة. الهوية المدارة هي طريقة لمصادقة واجهة برمجة التطبيقات الخاصة بك إلى خدمات Azure الأخرى. في Azure API Management، تحتاج إلى تطبيق الهوية المدارة في عدة أماكن وهي:
مستوى مثيل APIM، يمكنك تمكين الهوية المدارة في مثيل APIM عن طريق تعيين الخاصية
identity
علىSystemAssigned
مثل ذلك:resource apimService 'Microsoft.ApiManagement/service@2023-09-01-preview' = { name: name location: location tags: union(tags, { 'azd-service-name': name }) sku: { name: sku capacity: (sku == 'Consumption') ? 0 : ((sku == 'Developer') ? 1 : skuCount) } properties: { publisherEmail: publisherEmail publisherName: publisherName // Custom properties are not supported for Consumption SKU } identity: { type: 'SystemAssigned' } }
ينشئ هذا الإجراء هوية مدارة لمثيل APIM الذي يمكننا استخدامه لاحقا لمثيل APIM الخاص بنا، على سبيل المثال، مثيل Azure OpenAI.
مستوى واجهة برمجة التطبيقات، بالنسبة لمثيل API الخاص بك، يمكنك إقرانه بنهج. في النهج المذكور، يمكنك إضافة الإرشادات المطلوبة للهوية المدارة للعمل:
<policies> <inbound> <base /> <authentication-managed-identity resource="https://cognitiveservices.azure.com" output-token-variable-name="managed-id-access-token" ignore-error="false" /> <set-header name="Authorization" exists-action="override"> <value>@("Bearer " + (string)context.Variables["managed-id-access-token"])</value> </set-header> </inbound> <backend> <base /> </backend> <outbound> <base /> </outbound> <on-error> <base /> </on-error> </policies>
راجع الاستدعاءات السابقة إلى
authentication-managed-identity
وتأكدset-header
من تطبيق الهوية المدارة على واجهة برمجة التطبيقات.أخيرا، يشير مستوى الواجهة الخلفية، توفير الواجهات الخلفية إلى مثيلات Azure OpenAI. نحن بحاجة إلى توصيل مثيل APIM الخاص بنا بمثيل/مثيلات Azure OpenAI. لإجراء هذا الاتصال، إليك تعليمات Bicep:
resource role 'Microsoft.Authorization/roleAssignments@2022-04-01' = { name: guid(subscription().id, resourceGroup().id, principalId, roleDefinitionId) properties: { principalId: principalId principalType: "ServicePrincipal" roleDefinitionId: resourceId('Microsoft.Authorization/roleDefinitions', roleDefinitionId) } }
الفكرة مع تعليمات Bicep أعلاه هي إنشاء تعيين دور بين مثيل APIM ومثيل Azure OpenAI. في هذه الحالة:
-
principalId
هو معرف الهوية من مثيل APIM، -
roleDefinitionId
هو المستخدم المحدد، في هذه الحالة هو مستخدم يسمى "مستخدم الخدمات المعرفية"، وهو مستخدم لديه حق الوصول إلى مثيل Azure OpenAI. -
name
، تضمن هذه الخاصية تطبيق تعيين الدور على النطاق الصحيح، وهو في هذه الحالة اشتراك معين ومجموعة موارد. (يجب أن تكون نفس مجموعة الموارد مثل مثيل Azure OpenAI)
-