Indicazioni sulla limitazione di API per i partner che chiamano le API del Centro per i partner
Microsoft sta implementando la limitazione delle API per consentire prestazioni più coerenti entro un intervallo di tempo per i partner che chiamano le API del Centro per i partner. La limitazione delle richieste limita il numero di richieste inviate a un servizio in un intervallo di tempo per evitarne l'utilizzo eccessivo. Il Centro per i partner è progettato per gestire un volume elevato di richieste, ma se un viene effettuato numero eccessivo di richieste da pochi partner, la limitazione delle richieste consentirà di mantenere le prestazioni e l'affidabilità a un livello ottimale per tutti i partner.
I limiti delle richieste variano in base allo scenario. Ad esempio, se si esegue un volume elevato di scritture, la possibilità di limitazione è superiore rispetto a se si eseguono solo letture.
Cosa accade quando si verifica la limitazione?
Quando viene superata una soglia di limitazione, il Centro per i partner limita per un periodo di tempo qualsiasi ulteriore richiesta da tale client. Il comportamento di limitazione dipende dal tipo e dal numero di richieste.
Scenari comuni di limitazione delle richieste
Le cause più comuni della limitazione dei client includono:
- Un numero elevato di richieste per un ID TENANT per OGNI PARTNER: per alcune API del Centro per i partner, la limitazione è determinata dall'ID tenant del partner. Troppe chiamate a tali API nello stesso ID tenant partner comportano il superamento della soglia di limitazione.
- Un numero elevato di richieste per un ID tenant per ogni tenant partner per OGNI ID tenant del cliente: per altre API, la limitazione è determinata dalla combinazione id tenant partner/ID tenant cliente; in questi casi, effettuare troppe chiamate rispetto allo stesso ID tenant del cliente comporta una limitazione delle richieste, mentre le chiamate contro altri clienti potrebbero avere esito positivo.
Procedure consigliate per gestire la limitazione delle richieste
Le procedure di programmazione, ad esempio il polling continuo di una risorsa per verificare la disponibilità di aggiornamenti e l'analisi regolare delle raccolte di risorse per verificare la presenza di risorse nuove o eliminate, comportano maggiori probabilità di limitare e ridurre le prestazioni complessive. Le chiamate API simultanee possono causare un numero elevato di richieste per unità, causando la limitazione delle richieste. È invece consigliabile usare il rilevamento delle modifiche e le notifiche delle modifiche. Inoltre, dovrebbe essere possibile usare i log attività per rilevare le modifiche. Per altre informazioni, vedere Log attività del Centro per i partner. È consigliabile che i partner considerino l'uso dell'API del log attività per una maggiore efficienza ed evitare limitazioni. Vedere anche l'esempio di uso dei log attività, di seguito.
Procedure consigliate per gestire la limitazione delle richieste
Di seguito sono riportate le procedure consigliate per la gestione della limitazione:
- Ridurre il grado di parallelismo.
- Ridurre la frequenza delle chiamate.
- Evitare tentativi immediati perché tutte le richieste si accumulano rispetto ai limiti di utilizzo.
Quando si implementa la gestione degli errori, usare il codice di errore HTTP 429 per rilevare la limitazione delle richieste. La risposta non riuscita include l'intestazione della risposta retry-after. La riduzione delle richieste tramite il ritardo retry-after è il modo più rapido per eseguire il recupero dalla limitazione delle richieste.
Per usare il ritardo Retry-after:
- Attendere il numero di secondi specificati nell'intestazione Retry-After.
- Ripetere la richiesta.
- Se la richiesta ha esito negativo di nuovo con un codice errore 429, la limitazione è ancora in corso. Riprovare con il backoff Esponenziale, usare il ritardo Retry-After consigliato e ripetere la richiesta fino a quando non riesce.
- Se si usa l'SDK, si riceve un'eccezione con il codice di stato 429 quando la richiesta viene limitata. Utilizzare la proprietà RetryAfter nell'eccezione e ripetere la richiesta dopo che è trascorso il tempo.
API attualmente interessate dalla limitazione
Alla fine, ogni singola API del Centro per i partner che chiama l'endpoint "api.partnercenter.microsoft.com/" viene limitata. Attualmente, i limiti di limitazione vengono applicati solo alle API elencate di seguito. Il Centro per i partner raccoglie i dati di telemetria in ognuna delle API e regola in modo dinamico i limiti di limitazione. Nella tabella seguente sono elencate le API in cui è attualmente applicata la limitazione.
Operazione | Documentazione del Centro per i partner |
---|---|
{baseURL}/v1/customers/{customer_id}/orders | creare un ordine |
{baseURL}/v1/customers/{customer-tenant-id}/subscriptions/{id-for-subscription}/upgrades | transizione di una sottoscrizione |
{baseURL}/v1/customers/{customer-tenant-id}/orders/{order-id} | acquistare un componente aggiuntivo per una sottoscrizione |
{baseURL}/v1/customers/{customer-id}/carts/{cart-id} | creare un carrello |
{baseURL}/v1/customers/{customer-id}/carts/{cart-id}/checkout | estrai un carrello |
{baseURL}/v1/customers/{customer-id}/carts/{cart-id} | aggiornare un carrello |
{baseURL}/v1/customers/{customer-id}/subscriptions/{subscription-id}/registrations | registrare una sottoscrizione |
{baseURL}/v1/productupgrades | Creare un'entità di aggiornamento del prodotto |
{baseURL}/v1/customers/{customer-id}/subscriptions/{subscription-id}/conversions | convertire una sottoscrizione di valutazione a pagamento |
{baseURL}/v1/customers/{customer-tenant-id} | ottenere un cliente in base all'ID |
{baseURL}/v1/customers/{customer-tenant-id} | eliminare un account cliente dalla sandbox |
{baseURL}/v1/customers?size={size} | ottenere un elenco di clienti |
{baseURL}/v1/productUpgrades/idoneità | ottenere l'idoneità per l'aggiornamento del prodotto |
{baseURL}/v1/customers/{customer-tenant-id}/subscriptions/{id-for-subscription} | gestire la sottoscrizione |
{baseURL}/v1/customers/{customer_id}/subscriptions | get-all-of-a-customer-s-subscriptions |
{baseURL}/v1/customers/{customer_id}/subscriptions/{subscription_id} | Ottenere un abbonamento in base all'ID |
{baseURL}/v1/customers/{customer_id}/orders | Ottenere tutti gli ordini di un cliente |
{baseURL}/v1/customers/{customer_id}/orders/{order_id} | Ottenere un ordine in base all'ID |
{baseURL}/v1/customers/{customer_id}/orders/{order_id}/provisioningstatus | Ottenere lo stato del provisioning di un abbonamento |
{baseURL}/v1/customers/{customer_id}/subscriptions/{subscription_id} | Gestire gli ordini e gestire una sottoscrizione |
{baseURL}/v1/customers/{customer_id}/subscriptions/{subscription_id}/addons | Ottenere un elenco dei componenti aggiuntivi per un abbonamento |
{baseURL}/v1/customers/{customer_id}/subscriptions/{subscription_id}/azureEntitlements | Ottenere un elenco dei diritti di Azure per una sottoscrizione |
{baseURL}/v1/customers/{customer_id}/subscriptions/{subscription_id}/registrationstatus | Ottenere lo stato della registrazione di un abbonamento |
{baseURL}/v1/customers/{customer-tenant-id}/transfers | Ottenere tutti i trasferimenti di un cliente |
{baseURL}/v1/productUpgrades/{upgrade-id}/status | Ottenere lo stato di aggiornamento dei prodotti |
{baseURL}/v1/customers/{customer-id}/subscriptions/{subscription-id}/conversions | Ottenere un elenco delle offerte di conversione della copia di valutazione |
{baseURL}/v1/customers/{customer-tenant-id}/migrations/new commerce/validate | Convalidare una sottoscrizione per la migrazione |
{baseURL}/v1/customers/{customer-tenant-id}/migrations/new commerce | Creare una nuova migrazione commerciale |
{baseURL}/v1/customers/{customerId}/promotionEligibilities | Verificare l'idoneità per una promozione |
Risposta del codice di errore:
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." }
Esempio di log attività
Per la procedura consigliata per l'analisi delle modifiche giornaliere, è consigliabile eseguire query sui record di controllo per un giorno specifico.
Nella risposta si ottiene un risultato con le modifiche apportate a un tipo di operazione specifico. È possibile filtrare in base all'operazione di cui ci si occupa. Ad esempio, se si è interessati a un cliente appena creato, è possibile esaminare operationType = "add_customer".
L'elenco di operationtype/resources è disponibile nella documentazione dell'API.
Risposta di esempio
Richiesta:
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
Risposta:
{
"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": "aaaabbbb-0000-cccc-1111-dddd2222eeee",
"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": "aaaabbbb-0000-cccc-1111-dddd2222eeee",
"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"
}
}