Wskazówki dotyczące ograniczania interfejsu API dla partnerów wywołujących interfejsy API Centrum partnerskiego
Firma Microsoft implementuje ograniczanie przepływności interfejsu API, aby zapewnić bardziej spójną wydajność w danym przedziale czasu dla partnerów wywołujących interfejsy API Centrum partnerskiego. Ograniczanie przepustowości ogranicza liczbę równoczesnych wywołań usługi w przedziale czasu, co zapobiega nadmiernemu zużyciu zasobów. Chociaż Centrum partnerskie jest przeznaczone do obsługi dużej liczby żądań, ograniczanie przepustowości pomaga utrzymać optymalną wydajność i niezawodność dla wszystkich partnerów, jeśli przytłaczająca liczba żądań pochodzi od kilku z nich.
Limity ograniczania przepustowości różnią się w zależności od scenariusza. Jeśli na przykład wykonujesz dużą liczbę zapisów, możliwość ograniczania przepustowości jest wyższa niż w przypadku wykonywania tylko operacji odczytu.
Co się stanie w przypadku wystąpienia ograniczania przepustowości?
Po przekroczeniu progu ograniczania centrum partnerskiego ogranicza wszelkie dalsze żądania od tego klienta przez pewien czas. Zachowanie ograniczania przepustowości zależy od typu i liczby żądań.
Typowe scenariusze ograniczania przepustowości
Najczęstsze przyczyny ograniczania przepustowości klientów to:
- Duża liczba żądań interfejsu API dla identyfikatora dzierżawy partnera: w przypadku niektórych interfejsów API Centrum partnerskiego ograniczanie jest określane przez identyfikator dzierżawy partnera. Zbyt wiele wywołań do tych interfejsów API w tym samym identyfikatorze dzierżawy partnera powoduje przekroczenie progu ograniczania przepustowości.
- Duża liczba żądań dla interfejsu API dla identyfikatora dzierżawy partnera na identyfikator dzierżawy klienta: w przypadku innych interfejsów API ograniczanie jest określane przez kombinację identyfikatora dzierżawy partnera/identyfikatora dzierżawy klienta. W takich przypadkach wykonywanie zbyt wielu wywołań względem tego samego identyfikatora dzierżawy klienta powoduje ograniczenie przepustowości — podczas gdy wywołania względem innych klientów mogą zakończyć się powodzeniem.
Najlepsze rozwiązania dotyczące unikania ograniczania przepustowości
Praktyki programistyczne, takie jak ciągłe sondowanie zasobu w celu sprawdzania dostępności aktualizacji i regularnego skanowania kolekcji zasobów w celu sprawdzenia nowych lub usuniętych zasobów, mogą prowadzić do ograniczenia przepustowości i obniżenia ogólnej wydajności. Współbieżne wywołania interfejsu API mogą prowadzić do dużej liczby żądań na jednostkę, co powoduje ograniczanie żądań. Zamiast tego należy używać śledzenia zmian i powiadomień o zmianach. Ponadto powinno być możliwe używanie dzienników aktywności do wykrywania zmian. Aby uzyskać więcej informacji, zobacz Dzienniki aktywności Centrum partnerskiego. Zdecydowanie zalecamy partnerom rozważenie korzystania z interfejsu API dziennika aktywności w celu zwiększenia wydajności i uniknięcia ograniczania przepustowości. Zobacz również przykład użycia dzienników aktywności poniżej.
Najlepsze rozwiązania dotyczące obsługi ograniczania przepustowości
Poniżej przedstawiono najlepsze rozwiązania dotyczące obsługi ograniczania przepustowości:
- Zmniejsz stopień równoległości.
- Zmniejsz częstotliwość wywołań.
- Unikaj natychmiastowych ponownych prób, ponieważ wszystkie żądania wliczają się do limitów użycia.
Podczas wdrażania obsługi błędów użyj kodu błędu HTTP 429, aby wykryć ograniczenia przepustowości. Odpowiedź zakończona niepowodzeniem zawiera nagłówek odpowiedzi Retry-After. Wycofywanie żądań poprzez ponowienie próby po opóźnieniu to najszybszy sposób na odzyskiwanie po ograniczeniu przepustowości.
Aby użyć opóźnienia ponawiania prób:
- Zaczekaj przez liczbę sekund określoną w nagłówku Ponów próbę po.
- Ponów próbę żądania.
- Jeśli żądanie ponownie zakończy się niepowodzeniem z kodem błędu 429, nadal jest ograniczane. Ponów próbę z wycofywaniem wykładniczym, użyj zalecanego opóźnienia ponawiania próby i ponów próbę żądania, aż zakończy się powodzeniem.
- Jeśli używasz zestawu SDK, otrzymasz wyjątek z kodem stanu 429, gdy żądanie jest ograniczane. Użyj właściwości RetryAfter w wyjątku i ponów próbę żądania po upłynięciu czasu.
Interfejsy API, których obecnie dotyczy ograniczanie przepustowości
W końcu każdy pojedynczy interfejs API Centrum partnerskiego, który wywołuje punkt końcowy "api.partnercenter.microsoft.com/", jest ograniczany. Obecnie limity ograniczania przepustowości są wymuszane tylko w interfejsach API wymienionych poniżej. Centrum partnerskie zbiera dane telemetryczne dla każdego z interfejsów API i dynamicznie dostosowuje limity ograniczania przepustowości. W poniższej tabeli wymieniono interfejsy API, w których obecnie jest wymuszana ograniczanie przepustowości.
Operacja | Dokumentacja Centrum partnerskiego |
---|---|
{baseURL}/v1/customers/{customer_id}/orders | tworzenie zamówienia |
{baseURL}/v1/customers/{customer-tenant-id}/subscriptions/{id-for-subscription}/upgrades | przenoszenie subskrypcji |
{baseURL}/v1/customers/{customer-tenant-id}/orders/{order-id} | kupowanie dodatku do subskrypcji |
{baseURL}/v1/customers/{customer-id}/carts/{cart-id} | tworzenie koszyka |
{baseURL}/v1/customers/{customer-id}/carts/{cart-id}/checkout | wyewidencjonuj koszyk |
{baseURL}/v1/customers/{customer-id}/carts/{cart-id} | aktualizowanie koszyka |
{baseURL}/v1/customers/{customer-id}/subscriptions/{subscription-id}/registrations | rejestrowanie subskrypcji |
{baseURL}/v1/productupgrades | tworzenie jednostki uaktualniania produktu |
{baseURL}/v1/customers/{customer-id}/subscriptions/{subscription-id}/conversions | konwertowanie subskrypcji próbnej na płatną |
{baseURL}/v1/customers/{customer-tenant-id} | pobieranie klienta według identyfikatora |
{baseURL}/v1/customers?size={size} | uzyskiwanie listy klientów |
{baseURL}/v1/productUpgrades/uprawnienia | uzyskiwanie uprawnień do uaktualnienia produktu |
{baseURL}/v1/customers/{customer-tenant-id}/subscriptions/{id-for-subscription} | zarządzanie subskrypcją |
{baseURL}/v1/customers/{customer_id}/subscriptions | get-all-of-a-customer-s-subscriptions |
{baseURL}/v1/customers/{customer_id}/subscriptions/{subscription_id} | Pobieranie subskrypcji według identyfikatora |
{baseURL}/v1/customers/{customer_id}/orders | Pobieranie wszystkich zamówień klientów |
{baseURL}/v1/customers/{customer_id}/orders/{order_id} | Pobieranie zamówienia według identyfikatora |
{baseURL}/v1/customers/{customer_id}/orders/{order_id}/provisioningstatus | Uzyskiwanie stanu aprowizacji subskrypcji |
{baseURL}/v1/customers/{customer_id}/subscriptions/{subscription_id} | Zarządzanie zamówieniami i zarządzanie subskrypcją |
{baseURL}/v1/customers/{customer_id}/subscriptions/{subscription_id}/addons | Pobieranie listy dodatków dla subskrypcji |
{baseURL}/v1/customers/{customer_id}/subscriptions/{subscription_id}/azureEntitlements | Pobieranie listy uprawnień platformy Azure dla subskrypcji |
{baseURL}/v1/customers/{customer_id}/subscriptions/{subscription_id}/registrationstatus | Uzyskiwanie stanu rejestracji subskrypcji |
{baseURL}/v1/customers/{customer-tenant-id}/transfery | Pobieranie wszystkich transferów klienta |
{baseURL}/v1/productUpgrades/{upgrade-id}/status | Uzyskiwanie stanu uaktualnienia produktu |
{baseURL}/v1/customers/{customer-id}/subscriptions/{subscription-id}/conversions | Pobieranie listy ofert konwersji wersji próbnej |
{baseURL}/v1/customers/{customer-tenant-id}/migrations/newcommerce/validate | Weryfikowanie subskrypcji na potrzeby migracji |
{baseURL}/v1/customers/{customer-tenant-id}/migrations/newcommerce | Tworzenie migracji do nowego środowiska handlowego |
{baseURL}/v1/customers/{customerId}/promotionEligibilities | Weryfikowanie uprawnień do podwyższenia poziomu |
Odpowiedź kodu błędu:
HTTP/1.1 429 Too Many Requests
Content-Length: 84
Content-Type: application/json
Retry-After: 57
Date: Tue, 21 Jul 2020 04:10:58 GMT
{ "statusCode": 429, "message": "Rate limit is exceeded. Try again in 57 seconds." }
Przykład dziennika aktywności
Aby uzyskać najlepsze rozwiązanie w analizowaniu codziennych zmian, zalecamy wykonywanie zapytań dotyczących rekordu inspekcji dla określonego dnia.
W odpowiedzi otrzymasz wynik ze zmianami określonego typu operacji. Możesz filtrować na podstawie operacji, którą chcesz zastosować. Jeśli na przykład interesuje Cię nowo utworzony klient, możesz przyjrzeć się parametrowi operationType = "add_customer".
Listę elementów operationtype/resources można znaleźć w tych dokumentach interfejsu API.
Przykład odpowiedzi
Żądanie:
Http Get call: https://api.partnercenter.microsoft.com/v1/auditrecords?startDate=2020-09-02&endDate=2020-09-02&size=50
Authorization: Bearer <token>
Accept: application/json
MS-RequestId: 127facaa-e389-41f8-8bb7-1d1af99db893
MS-CorrelationId: aaaa0000-bb11-2222-33cc-444444dddddd
X-Locale: en-US
Host: api.partnercenter.microsoft.com
Connection: Keep-Alive
Odpowiedź:
{
"totalCount": 17,
"items": [
{
"id": "9daaeb1c-4195-4db5-9f1d-509eb70c8c2d_e905b566-4779-4e57-944c-7b1b5312705b_updatecustomeruserlicenses_637346859797753934",
"partnerId": "9daaeb1c-4195-4db5-9f1d-509eb70c8c2d",
"participants": [
"9daaeb1c-4195-4db5-9f1d-509eb70c8c2d"
],
"customerId": "e905b566-4779-4e57-944c-7b1b5312705b",
"userPrincipalName": "admin@testsw09.onmicrosoft.com",
"applicationId": "FulfillmentService",
"resourceType": "license",
"operationType": "update_customer_user_licenses",
"operationDate": "2020-09-02T23:26:19.7753934Z",
"operationStatus": "succeeded",
"customizedData": [
{
"key": "CustomerUserId",
"value": "933808c7-b165-496c-a24e-1a4b7846fab4"
}
],
"attributes": {
"objectType": "AuditRecord"
}
},
{
"id": "9daaeb1c-4195-4db5-9f1d-509eb70c8c2d_86bddccf-9a53-40c6-907c-08067a3f8da7_ia80zlkxp6ewoqpp35pbqjlhqv9iigvz1_createorder_637346662909268372",
"partnerId": "9daaeb1c-4195-4db5-9f1d-509eb70c8c2d",
"participants": [
"9daaeb1c-4195-4db5-9f1d-509eb70c8c2d"
],
"customerId": "aaaabbbb-0000-cccc-1111-dddd2222eeee",
"customerName": "CustomMetersStagingTest",
"userPrincipalName": "admin@testsw09.onmicrosoft.com",
"applicationId": "00001111-aaaa-2222-bbbb-3333cccc4444",
"resourceType": "order",
"resourceNewValue": "{\"Id\":\"Ia80ZLkXp6eWOqpp35pBQJLhqv9IiGVZ1\",\"AlternateId\":\"64144d300bde\",\"ReferenceCustomerId\":\"aaaabbbb-0000-cccc-1111-dddd2222eeee\",\"BillingCycle\":\"monthly\",\"CurrencyCode\":\"USD\",\"CurrencySymbol\":\"$\",\"LineItems\":[{\"LineItemNumber\":0,\"ProvisioningContext\":null,\"OfferId\":\"DZH318Z0C964:0001:DZH318Z0BZDG\",\"SubscriptionId\":\"aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e\",\"ParentSubscriptionId\":null,\"TermDuration\":\"P1M\",\"TransactionType\":\"New\",\"FriendlyName\":\"SaaS custom meter offer - Bronze\",\"Quantity\":1,\"Pricing\":null,\"PartnerIdOnRecord\":null,\"RenewsTo\":null,\"Links\":{\"Product\":{\"Uri\":\"/products/DZH318Z0C964?country=US\",\"Method\":\"GET\",\"Body\":null,\"Headers\":[]},\"Sku\":{\"Uri\":\"/products/DZH318Z0C964/skus/0001?country=US\",\"Method\":\"GET\",\"Body\":null,\"Headers\":[]},\"Availability\":{\"Uri\":\"/products/DZH318Z0C964/skus/0001/availabilities/DZH318Z0BZDG?country=US\",\"Method\":\"GET\",\"Body\":null,\"Headers\":[]},\"ActivationLinks\":{\"Uri\":\"/customers/aaaabbbb-0000-cccc-1111-dddd2222eeee/orders/Ia80ZLkXp6eWOqpp35pBQJLhqv9IiGVZ1/lineitems/0/activationlinks\",\"Method\":\"GET\",\"Body\":null,\"Headers\":[]}}}],\"CreationDate\":\"2020-09-02T17:58:01.7755853Z\",\"Status\":\"pending\",\"TransactionType\":\"UserPurchase\",\"Links\":{\"Self\":{\"Uri\":\"/customers/aaaabbbb-0000-cccc-1111-dddd2222eeee/orders/Ia80ZLkXp6eWOqpp35pBQJLhqv9IiGVZ1\",\"Method\":\"GET\",\"Body\":null,\"Headers\":[]},\"ProvisioningStatus\":{\"Uri\":\"/customers/aaaabbbb-0000-cccc-1111-dddd2222eeee/orders/Ia80ZLkXp6eWOqpp35pBQJLhqv9IiGVZ1/provisioningstatus\",\"Method\":\"GET\",\"Body\":null,\"Headers\":[]},\"PatchOperation\":{\"Uri\":\"/customers/aaaabbbb-0000-cccc-1111-dddd2222eeee/orders/Ia80ZLkXp6eWOqpp35pBQJLhqv9IiGVZ1\",\"Method\":\"PATCH\",\"Body\":null,\"Headers\":[]}},\"Client\":{\"marketplaceCountry\":\"US\",\"deviceFamily\":\"UniversalStore-PartnerCenter\",\"name\":\"Partner Center Web\"},\"Attributes\":{\"ObjectType\":\"Order\"}}",
"operationType": "create_order",
"originalCorrelationId": "96514ebe-c1b2-4865-cb46-2c2d20a2e911",
"operationDate": "2020-09-02T17:58:10.9268372Z",
"operationStatus": "succeeded",
"customizedData": [
{
"key": "OrderId",
"value": "Ia80ZLkXp6eWOqpp35pBQJLhqv9IiGVZ1"
},
{
"key": "AlternateId",
"value": "64144d300bde"
},
{
"key": "BillingCycle",
"value": "Monthly"
},
{
"key": "OfferId-0",
"value": "DZH318Z0C964:0001:DZH318Z0BZDG"
},
{
"key": "SubscriptionId-0",
"value": "aaaa0a0a-bb1b-cc2c-dd3d-eeeeee4e4e4e"
},
{
"key": "SubscriptionName-0",
"value": "SaaS custom meter offer - Bronze"
},
{
"key": "Quantity-0",
"value": "1"
},
{
"key": "PartnerOnRecord-0",
"value": null
}
],
"attributes": {
"objectType": "AuditRecord"
}
},
{
"id": "9daaeb1c-4195-4db5-9f1d-509eb70c8c2d_86bddccf-9a53-40c6-907c-08067a3f8da7_86bddccf-9a53-40c6-907c-08067a3f8da7_addcustomer_637346648528069005",
"partnerId": "9daaeb1c-4195-4db5-9f1d-509eb70c8c2d",
"participants": [
"9daaeb1c-4195-4db5-9f1d-509eb70c8c2d"
],
"customerId": "aaaabbbb-0000-cccc-1111-dddd2222eeee",
"customerName": "CustomMetersStagingTest",
"userPrincipalName": "admin@testsw09.onmicrosoft.com",
"applicationId": "00001111-aaaa-2222-bbbb-3333cccc4444",
"resourceType": "customer",
"resourceNewValue": "{\"Id\":\"aaaabbbb-0000-cccc-1111-dddd2222eeee\",\"CommerceId\":\"9dd78b4f-f98a-44b4-a2fa-2b82ac58d24c\",\"CompanyProfile\":{\"TenantId\":\"aaaabbbb-0000-cccc-1111-dddd2222eeee\",\"Domain\":\"CustomMetersStagingTest.onmicrosoft.com\",\"CompanyName\":\"CustomMetersStagingTest\",\"Address\":null,\"Email\":null,\"OrganizationRegistrationNumber\":null,\"Links\":{\"Self\":{\"Uri\":\"/customers/aaaabbbb-0000-cccc-1111-dddd2222eeee/profiles/company\",\"Method\":\"GET\",\"Body\":null,\"Headers\":[]}},\"Attributes\":{\"ObjectType\":\"CustomerCompanyProfile\"}},\"BillingProfile\":{\"Id\":\"bbbbcccc-1111-dddd-2222-eeee3333ffff\",\"FirstName\":\"CustomMetersStagingTest\",\"LastName\":\"CustomMetersStagingTest\",\"Email\":\"CustomMetersStagingTest@CustomMetersStagingTest.com\",\"Culture\":\"en-US\",\"Language\":\"en\",\"CompanyName\":\"CustomMetersStagingTest\",\"DefaultAddress\":{\"Id\":null,\"Country\":\"US\",\"Region\":null,\"City\":\"Seattle\",\"State\":\"WA\",\"District\":null,\"AddressLine1\":\"CustomMetersStagingTest\",\"AddressLine2\":null,\"AddressLine3\":null,\"PostalCode\":\"98122\",\"FirstName\":\"CustomMetersStagingTest\",\"LastName\":\"CustomMetersStagingTest\",\"EmailAddress\":null,\"PhoneNumber\":null,\"MiddleName\":null},\"Attributes\":{\"Etag\":\"-2279334701316321663\",\"ObjectType\":\"CustomerBillingProfile\"}},\"RelationshipToPartner\":\"reseller\",\"AllowDelegatedAccess\":true,\"UserCredentials\":{\"userName\":\"admin\",\"password\":\"\"},\"AssociatedPartnerId\":null,\"CustomDomains\":null,\"Attributes\":{\"ObjectType\":\"Customer\"}}",
"operationType": "add_customer",
"originalCorrelationId": "7550d9ea-e64a-416f-e49b-3670c516cf69",
"operationDate": "2020-09-02T17:34:12.8069005Z",
"operationStatus": "succeeded",
"customizedData": [
{
"key": "PrimaryDomainName",
"value": "CustomMetersStagingTest.onmicrosoft.com"
},
{
"key": "Relationship",
"value": "Reseller"
}
],
"attributes": {
"objectType": "AuditRecord"
}
},
...
],
"links": {
"self": {
"uri": "/auditrecords?startDate=2020-09-02&endDate=2020-09-02&size=50",
"method": "GET",
"headers": []
}
},
"attributes": {
"objectType": "Collection"
}
}