API Management
Więc jaki jest problem, który sprawia, że chcę szukać rozwiązania do zarządzania interfejsami API? Najprawdopodobniej masz następujące wyzwania:
- Skalowanie, interfejsy API lub interfejsy API są używane przez wielu klientów w różnych regionach świata i musisz upewnić się, że jest ona dostępna i elastyczna.
- Zabezpieczenia, należy upewnić się, że interfejs API jest bezpieczny i że tylko autoryzowani klienci mogą uzyskać do niego dostęp.
- Zarządzanie błędami, należy upewnić się, że interfejs API może bezpiecznie obsługiwać błędy.
- Monitorowanie wymaga monitorowania interfejsów API, aby upewnić się, że działa zgodnie z oczekiwaniami.
- Odporność, musisz upewnić się, że interfejs API jest odporny i może bezpiecznie obsługiwać błędy.
Dla każdego z tych wyzwań można wybrać rozwiązanie punktowe, ale może to być trudne do zarządzania. Należy również pamiętać, że interfejsy API mogą być wbudowane w różne stosy technologiczne, co oznacza, że rozwiązania powyższych wyzwań mogą oznaczać, że potrzebujesz różnych rozwiązań dla każdego interfejsu API. Jeśli masz wszystkie te wyzwania, rozważ scentralizowane rozwiązanie do zarządzania interfejsami API, takie jak usługa Azure API Management.
Przyjrzyjmy się bliżej pewnym wyzwaniom i zobaczmy, jak scentralizowane rozwiązanie do zarządzania interfejsami API, takie jak usługa Azure API Management, może pomóc w ich rozwiązaniu.
Infrastruktura jako kod, IaC
Doskonale sprawdza się, tworząc zasoby platformy Azure przy użyciu witryny Azure Portal, ale wraz ze wzrostem infrastruktury zarządzanie nią staje się trudniejsze. Jednym z napotkanych problemów jest to, że nie można łatwo replikować infrastruktury w innym środowisku.
Trudno jest również śledzić wszystkie zmiany wprowadzone w infrastrukturze. W takiej sytuacji pojawia się infrastruktura jako kod (IaC). IaC to praktyka zarządzania infrastrukturą przy użyciu kodu. Aby zastosować IaC na platformie Azure, masz kilka opcji, z których jedna to Bicep. Bicep to język specyficzny dla domeny (DSL) do deklaratywnego wdrażania zasobów platformy Azure. Jest to doskonały sposób zarządzania zasobami w chmurze. Oto prosty przykład tego, jak wygląda Bicep:
param location string = 'eastus'
resource storageAccount 'Microsoft.Storage/storageAccounts@2021-06-01' = {
name: 'mystorageaccount'
location: location
kind: 'StorageV2'
sku: {
name: 'Standard_LRS'
}
}
W poprzednim przykładzie zdefiniowaliśmy konto magazynu przy użyciu Bicep. Zdefiniowaliśmy lokalizację konta magazynu, rodzaj konta magazynu i jednostkę SKU (jednostkę przechowywania zapasów). Lokalizacja to parametr, który możemy przekazać podczas wdrażania pliku Bicep. Aby wdrożyć przedstawiony plik, użyjemy interfejsu wiersza polecenia platformy Azure w następujący sposób:
az deployment group create --resource-group myResourceGroup --template-file main.bicep
Poprzednie polecenie wdraża konto magazynu w grupie myResourceGroup
zasobów i używa pliku main.bicep
Bicep do utworzenia zasobów w pliku.
Obsługa obciążenia za pośrednictwem modułu równoważenia obciążenia
Dodawanie konstrukcji równoważenia obciążenia jest odpowiedzią, gdy problem polega na tym, że interfejs API jest przeciążony żądaniami. Moduł równoważenia obciążenia może pomóc w rozłożeniu obciążenia między wiele wystąpień interfejsu API.
W usłudze Azure API Management równoważenie obciążenia jest implementowane przez zdefiniowanie koncepcji nazywanej zapleczami. Chodzi o skonfigurowanie wielu zapleczy odpowiadających punktom końcowym interfejsu API, a następnie utworzeniu modułu równoważenia obciążenia, który dystrybuuje obciążenie między te zaplecza. Oto jak wygląda architektura:
Co się dzieje w poprzedniej architekturze:
- Klient wysyła żądanie do wystąpienia usługi API Management.
- Żądanie jest uwierzytelniane i autoryzowane.
- Żądanie jest następnie wysyłane do modułu równoważenia obciążenia.
- Moduł równoważenia obciążenia dystrybuuje żądanie do jednego z zapleczy (wybrany interfejs API usługi Azure OpenAI jest wskazywany pogrubioną).
Zaplecze przetwarza żądanie i wysyła odpowiedź z powrotem do klienta.
Definiowanie modułu równoważenia obciążenia
Aby skonfigurować moduł równoważenia obciążenia w usłudze Azure API Management, należy wykonać następujące czynności:
- Zaplecza— tyle zapleczy, na których chcesz rozłożyć obciążenie.
- Moduł równoważenia obciążenia — moduł równoważenia obciążenia zawierający zaplecza, w których chcesz rozłożyć obciążenie.
- Zasady kierujące przychodzące wywołania do modułu równoważenia obciążenia.
Tworzenie zapleczy
Aby utworzyć zaplecze w usłudze Azure API Management, należy zdefiniować jednostkę zaplecza. Poniżej przedstawiono sposób definiowania zaplecza w aplikacji 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'
}
]
}
}
W poprzednim kodzie Bicep zaplecze jest definiowane w taki sposób, aby odpowiadało adresowi URL punktu końcowego interfejsu API. Zauważ również, że nazwa jest nazwą backend2
, która może być używana później. Dla każdego zaplecza, które masz, należy zakodować go jak poprzedni kod bicep.
Uwaga
Pamiętaj, że możesz mieć wiele zapleczy, aby można było zdefiniować dowolną liczbę zapleczy.
Tworzenie puli zaplecza
Następnie chcemy utworzyć pulę zaplecza, która konfiguruje, między którymi zapleczami chcemy rozdzielić obciążenie. Możemy zakodować tę pulę zaplecza jako jednostkę zaplecza w następujący sposób:
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}'
}
]
}
}
}
Zaplecze, które utworzyliśmy wcześniej, backend2
, jest przywoływane wraz z innym zapleczem backend1
, które pominięto w celu zwięzłości.
Możemy również uwzględnić priority
właściwość i weight
dla każdego elementu na services
liście, aby określić sposób dystrybucji obciążenia przez moduł równoważenia obciążenia. Poniżej przedstawiono sposób ustawiania priorytetu i wagi dla każdego zaplecza:
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
}
]
W poprzednim przykładzie moduł równoważenia obciążenia dystrybuuje obciążenie do backend-1
trzech razy więcej niż backend-2
.
Bezpośrednie połączenia przychodzące
Na koniec musimy kierować wszystkie przychodzące wywołania do tego zaplecza równoważenia obciążenia. Instrukcja kierunku jest tworzona następująca jednostka interfejsu 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'
}
}
Konfigurowanie zasad
Teraz na koniec możemy ustawić zasady dla wcześniej opisanego interfejsu API i kierować wywołania przychodzące do modułu równoważenia obciążenia:
// 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
}
}
Zrobiliśmy to, aby utworzyć zasady kierujące przychodzące wywołania do modułu równoważenia obciążenia. Zasady set-backend-service
służą do kierowania przychodzących wywołań do modułu równoważenia obciążenia. Właściwość backend-id
jest ustawiona na nazwę utworzonego wcześniej modułu równoważenia obciążenia.
Po zakończeniu wszystkich tych ruchomych części wystąpienie usługi API Management jest teraz zrównoważone. Teraz możesz skalować interfejs API, dodając więcej zapleczy do modułu równoważenia obciążenia.
Wyłącznik
Wyłącznik jest używany, gdy chcesz chronić interfejs API przed przeciążeniami żądań. Jak to działa, definiujesz zestaw reguł, które po spełnieniu wyzwalacz wyłącznika i zatrzymuje wysyłanie żądań do zaplecza. W usłudze Azure API Management można zdefiniować wyłącznik, konfigurując zaplecze i definiując regułę wyłącznika. Oto jak to zrobić:
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'
}
]
}
}
}
W poprzedniej definicji zaplecza istnieje właściwość failureCondition
, która definiuje, kiedy wyłącznik powinien się posuwać. W takim przypadku wyłącznik przechodzi w przypadku wystąpienia trzech błędów serwera w ciągu dnia. Właściwość tripDuration
określa, jak długo wyłącznik powinien pozostać otwarty przed ponownym zamknięciem. Dobrym rozwiązaniem jest zdefiniowanie wyłącznika dla każdego zaplecza, które znajduje się w wystąpieniu usługi API Management.
Tożsamość zarządzana
Innym problemem, który chcemy rozwiązać, jest bezpieczeństwo. Chcesz mieć pewność, że interfejs API jest bezpieczny i że tylko autoryzowani klienci mają do niego dostęp. Sposobem zabezpieczenia interfejsu API jest użycie tożsamości zarządzanej. Tożsamość zarządzana to sposób uwierzytelniania interfejsu API do innych usług platformy Azure. W usłudze Azure API Management należy zastosować tożsamość zarządzaną w kilku miejscach:
Poziom wystąpienia usługi APIM można włączyć tożsamość zarządzaną w wystąpieniu usługi APIM, ustawiając właściwość na następującą
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' } }
Ta akcja generuje tożsamość zarządzaną dla wystąpienia usługi APIM, którego możemy użyć później w ramach wystąpienia usługi APIM, na przykład wystąpienia usługi Azure OpenAI.
Poziom interfejsu API dla wystąpienia interfejsu API można skojarzyć go z zasadami. W podanych zasadach można dodać wymagane instrukcje dotyczące tożsamości zarządzanej, aby działały:
<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>
Zapoznaj się z poprzednimi wywołaniami
authentication-managed-identity
iset-header
te instrukcje upewnij się, że tożsamość zarządzana jest stosowana do interfejsu API.Na koniec poziom zaplecza, zapewniając, że zaplecza wskazują wystąpienia usługi Azure OpenAI. Musimy połączyć nasze wystąpienie usługi APIM z wystąpieniem/s usługi Azure OpenAI. Aby nawiązać to połączenie, oto instrukcja 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) } }
W przypadku powyższej instrukcji Bicep należy utworzyć przypisanie roli między wystąpieniem usługi APIM i wystąpieniem usługi Azure OpenAI. W takim przypadku:
principalId
to identyfikator tożsamości z wystąpienia usługi APIM,roleDefinitionId
jest konkretnym użytkownikiem, w tym przypadku jest to użytkownik o nazwie "Użytkownik usług Cognitive Services", użytkownik, który ma dostęp do wystąpienia usługi Azure OpenAI.name
Ta właściwość gwarantuje, że przypisanie roli jest stosowane do prawidłowego zakresu, co w tym przypadku jest określoną subskrypcją i grupą zasobów. (musi być tą samą grupą zasobów co wystąpienie usługi Azure OpenAI)