Instrucciones para la limitación de la API para los partners que llaman a las API del Centro de partners
Microsoft implementa la limitación de API para permitir un rendimiento más coherente dentro de un intervalo de tiempo para los asociados que llaman a las API del Centro de partners. La limitación se aplicará al número de solicitudes enviadas a un servicio dentro de un intervalo de tiempo con el fin de evitar el uso excesivo de los recursos. Si bien el Centro de partners está diseñado para administrar un gran volumen de solicitudes, si se produce un número abrumador de solicitudes de unos pocos partners, la limitación ayudará a mantener un rendimiento y una confiabilidad óptimos para todos los partners.
Las limitaciones varían según el escenario. Por ejemplo, si está realizando un gran volumen de escrituras, la posibilidad de limitación es mayor que si solo realiza lecturas.
¿Qué ocurre cuando se produce la limitación?
Cuando se supere un umbral de limitación, el Centro de partners limitará las solicitudes posteriores de ese cliente durante un período de tiempo. El comportamiento de limitación depende del tipo y el número de solicitudes.
Escenarios comunes de limitación
Las causas más comunes de limitación de clientes son:
- Un gran número de solicitudes para una API por identificador de inquilino de partner: para algunas API del Centro de partners, la limitación viene determinada por el identificador de inquilino del asociado. Hay demasiadas llamadas a esas API en el mismo identificador de inquilino de asociado, lo que provoca que se supere el umbral de limitación.
- Un gran número de solicitudes para una API por id. de inquilino de asociado por identificador de inquilino de cliente: para otras API, la limitación viene determinada por la combinación de id. de inquilino de partner o id. de inquilino de cliente; en esos casos, realizar demasiadas llamadas con el mismo identificador de inquilino de cliente da como resultado una limitación, mientras que las llamadas a otros clientes pueden realizarse correctamente.
Procedimientos recomendados para evitar las limitaciones
Las prácticas de programación, como sondear continuamente un recurso para buscar actualizaciones y examinar periódicamente las colecciones de recursos para comprobar los recursos nuevos o eliminados, son más probables que produzcan limitaciones y degradan el rendimiento general. Las llamadas API simultáneas pueden dar lugar a un gran número de solicitudes por unidad, lo que hace que las solicitudes se limite. En su lugar, debe usar el seguimiento de cambios y las notificaciones de cambios. Además, debe poder usar los registros de actividad para detectar cambios. Para obtener más información, consulte Registros de actividad del Centro de partners. Se recomienda encarecidamente a los asociados que consideren la posibilidad de usar la API de registro de actividad para obtener más eficacia y evitar la limitación. Consulte también el ejemplo de uso de registros de actividad, a continuación.
Procedimientos recomendados para tratar con las limitaciones
Estos son los procedimientos recomendados para controlar la limitación:
- Reduzca el grado de paralelismo.
- Reduzca la frecuencia de las llamadas.
- Evite reintentos inmediatos, ya que todas las solicitudes se acumulan en los límites de uso.
Cuando implemente el control de errores, utilice el código de error HTTP 429 para detectar la limitación. La respuesta con error incluye el encabezado de respuesta Retry-After. La forma más rápida de recuperarse de la limitación es realizar copias de seguridad de las solicitudes con el retraso de Retry-After.
Para usar el retraso Retry-after:
- Espere el número de segundos especificados en el encabezado Retry-After.
- Vuelva a intentarlo.
- Si se vuelve a producir un error en la solicitud con un código de error 429, significa que todavía está limitado. Vuelva a intentarlo con retroceso exponencial, use el retraso Retry-After recomendado y vuelva a intentar la solicitud hasta que se realice correctamente.
- Si usa el SDK, se iniciará una excepción con el código de estado 429 cuando se limita la solicitud. Utilice la propiedad RetryAfter en la excepción y vuelva a intentar la solicitud una vez haya transcurrido el tiempo.
API afectadas actualmente por la limitación
Al final, cada API del Centro de partners que llama al punto de conexión "api.partnercenter.microsoft.com/" se limita. Actualmente, los límites de limitación solo se aplican en las API que se enumeran a continuación. El Centro de partners recopila la telemetría en cada una de las API y ajusta dinámicamente los límites de limitación. En la tabla siguiente se enumeran las API en las que se aplica actualmente la limitación.
Operación | Documentación del Centro de partners |
---|---|
{baseURL}/v1/customers/{customer_id}/orders | crear un pedido |
{baseURL}/v1/customers/{customer-tenant-id}/subscriptions/{id-for-subscription}/upgrades | transición de una suscripción |
{baseURL}/v1/customers/{customer-tenant-id}/orders/{order-id} | comprar un complemento en una suscripción |
{baseURL}/v1/customers/{customer-id}/carts/{cart-id} | crear un carro |
{baseURL}/v1/customers/{customer-id}/carts/{cart-id}/checkout | desprotección de un carro |
{baseURL}/v1/customers/{customer-id}/carts/{cart-id} | actualizar un carro |
{baseURL}/v1/customers/{customer-id}/subscriptions/{subscription-id}/registrations | registrar una suscripción |
{baseURL}/v1/productupgrades | creación de una entidad de actualización de producto |
{baseURL}/v1/customers/{customer-id}/subscriptions/{subscription-id}/conversions | convertir una suscripción de prueba a pago |
{baseURL}/v1/customers/{customer-tenant-id} | obtener un cliente por identificador |
{baseURL}/v1/customers/{customer-tenant-id} | eliminar una cuenta de cliente del espacio aislado |
{baseURL}/v1/customers?size={size} | obtener una lista de clientes |
{baseURL}/v1/productUpgrades/eligibility | obtener elegibilidad para la actualización del producto |
{baseURL}/v1/customers/{customer-tenant-id}/subscriptions/{id-for-subscription} | administrar suscripción |
{baseURL}/v1/customers/{customer_id}/subscriptions | get-all-of-a-customer-s-subscriptions |
{baseURL}/v1/customers/{customer_id}/subscriptions/{subscription_id} | Obtener una suscripción según el id. |
{baseURL}/v1/customers/{customer_id}/orders | Obtención de todos los pedidos de un cliente |
{baseURL}/v1/customers/{customer_id}/orders/{order_id} | Obtener un pedido en función del id. |
{baseURL}/v1/customers/{customer_id}/orders/{order_id}/provisioningstatus | Obtener el estado de aprovisionamiento de la suscripción |
{baseURL}/v1/customers/{customer_id}/subscriptions/{subscription_id} | Administrar pedidos y administrar una suscripción |
{baseURL}/v1/customers/{customer_id}/subscriptions/{subscription_id}/addons | Obtener una lista de complementos para una suscripción |
{baseURL}/v1/customers/{customer_id}/subscriptions/{subscription_id}/azureEntitlements | Obtener una lista de derechos de Azure para una suscripción |
{baseURL}/v1/customers/{customer_id}/subscriptions/{subscription_id}/registrationstatus | Obtener el estado de registro de la suscripción |
{baseURL}/v1/customers/{customer-tenant-id}/transfers | Obtener todas las transferencias de un cliente |
{baseURL}/v1/productUpgrades/{upgrade-id}/status | Obtener el estado de actualización del producto |
{baseURL}/v1/customers/{customer-id}/subscriptions/{subscription-id}/conversions | Obtener una lista de ofertas de conversión de versiones de prueba |
{baseURL}/v1/customers/{customer-tenant-id}/migrations/newcommerce/validate | Validar una suscripción para la migración |
{baseURL}/v1/customers/{customer-tenant-id}/migrations/newcommerce | Crear una migración comercial |
{baseURL}/v1/customers/{customerId}/promotionEligibilities | Comprobación de la idoneidad de una promoción |
Respuesta del código de error:
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." }
Ejemplo de registro de actividad
Para obtener un procedimiento recomendado para analizar los cambios diarios, se recomienda consultar el registro de auditoría durante un día específico.
En la respuesta, obtendrá un resultado con cambios en un tipo de operación específico. Puede filtrar en función de la operación que le interesa. Por ejemplo, si está interesado en un cliente recién creado, puede ver operationType = "add_customer".
Puede encontrar una lista de operationtype/resources en estos documentos de API.
Ejemplo de respuesta
Solicitud:
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
Respuesta:
{
"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"
}
}