Управление API
Итак, какая проблема возникает у меня, что заставляет меня искать решение для управления API? Скорее всего, у вас есть следующие проблемы:
- Масштабирование API или API используется многими клиентами в разных регионах мира, и необходимо обеспечить доступность и реагирование.
- Необходимо обеспечить защиту API и доступ к нему могут только авторизованные клиенты.
- Для управления ошибками необходимо убедиться, что API может обрабатывать ошибки корректно.
- Мониторинг api необходимо отслеживать, чтобы убедиться, что он выполняется должным образом.
- Устойчивость, необходимо убедиться, что API устойчив и может корректно обрабатывать сбои.
Для каждой из этих проблем вы можете выбрать решение точки, но это может быть сложно управлять. Рассмотрите также, что API-интерфейсы могут быть созданы в разных технологических стеках, что означает, что решения, описанные выше, могут означать, что вам нужны различные решения для каждого API. Если у вас есть все эти проблемы, следует рассмотреть централизованное решение для управления API, например Azure Управление API.
Давайте более подробно рассмотрим некоторые проблемы и посмотрим, как централизованное решение для управления API, например Azure Управление API поможет вам устранить их.
Инфраструктура как код, IaC
Это прекрасно, создав ресурсы Azure с помощью портал 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
ресурсов и использует Bicep-файл main.bicep
для создания ресурсов в файле.
Обработка нагрузки с помощью подсистемы балансировки нагрузки
Добавление конструкции балансировки нагрузки — это ответ, когда проблема заключается в том, что API перегружен запросами. Подсистема балансировки нагрузки помогает распределять нагрузку между несколькими экземплярами API.
В службе Управление API Azure балансировка нагрузки реализуется путем определения концепции, называемой серверными службами. Идея заключается в том, что вы настроили множество внутренних серверных компонентов, соответствующих конечным точкам API, а затем создаете подсистему балансировки нагрузки, которая распределяет нагрузку между этими внутренними серверами. Вот как выглядит архитектура:
Что происходит в предыдущей архитектуре:
- Клиент отправляет запрос в экземпляр Управление API.
- Запрос проходит проверку подлинности и авторизован.
- Затем запрос отправляется в подсистему балансировки нагрузки.
- Подсистема балансировки нагрузки распределяет запрос на один из внутренних серверных компонентов (выбранный API OpenAI Azure указан полужирным шрифтом).
Серверная часть обрабатывает запрос и отправляет ответ клиенту.
Определение подсистемы балансировки нагрузки
Чтобы настроить подсистему балансировки нагрузки в Azure Управление API, необходимо выполнить следующие действия.
- Серверные серверы, как и многие серверные части, на которые вы хотите распределить нагрузку.
- Подсистема балансировки нагрузки— подсистема балансировки нагрузки, содержащая серверные серверы, по которым требуется распределить нагрузку.
- Политика , которая направляет входящие вызовы подсистеме балансировки нагрузки.
Создание серверных компонентов
Чтобы создать серверную часть в Azure Управление API, необходимо определить серверную сущность. Вот как можно определить серверную часть в 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-адресу конечной точки API, обратите внимание, что это имя 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'
}
}
Настройка политики
Теперь, наконец, мы можем задать политику на более ранних описанных API и направить входящие вызовы в подсистему балансировки нагрузки:
// 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
свойства задано имя созданного подсистемы балансировки нагрузки.
При этом все эти перемещающиеся части теперь балансируют нагрузку Управление API экземпляра. Теперь вы можете масштабировать API, добавив в подсистему балансировки нагрузки дополнительные серверные серверы.
Средство разбиения цепи
Средство автоматического останова — это то, что вы используете, если вы хотите защитить API от перегрузки по запросам. Как это работает, вы определяете набор правил, которые при выполнении активируются и перестают отправлять запросы в серверную часть. В Azure Управление API можно определить средство разбиения цепи, настроив серверную часть и определив правило разбиения цепи. Вот как это сделать:
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
определяет, как долго средство разбиения цепи должно оставаться открытым, прежде чем он снова закрывается. Рекомендуется определить выключатель для каждой серверной части, которую вы имеете в Управление API экземпляре.
Управляемое удостоверение
Другая проблема, которую мы хотим решить, — безопасность. Вы хотите убедиться, что API является безопасным и что к нему могут получить доступ только авторизованные клиенты. Способ защиты API — использовать управляемое удостоверение. Управляемое удостоверение — это способ проверки подлинности API в других службах Azure. В Azure Управление API необходимо применить управляемое удостоверение в нескольких местах:
Уровень экземпляра 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 для экземпляра 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
этими инструкциями, чтобы убедиться, что управляемое удостоверение применяется к API.Наконец, уровень серверной части, предоставляющий серверные части, указывают на экземпляры 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
— это конкретный пользователь, в этом случае это пользователь с именем Cognitive Services User, имеющий доступ к экземпляру Azure OpenAI.name
Это свойство гарантирует, что назначение роли применяется к правильной области, которая в данном случае является определенной подпиской и группой ресурсов. (должна быть той же группой ресурсов, что и экземпляр Azure OpenAI)