Diagnóstico y solución de problemas de tiempo de espera de la solicitud del SDK de .NET en Azure Cosmos DB

SE APLICA A: NoSQL

El error HTTP 408 se produce si el SDK no puede completar la solicitud antes de que se agote el límite de tiempo de espera.

Es importante asegurarse de que el diseño de la aplicación siga nuestra guía para diseñar aplicaciones resistentes con SDK de Azure Cosmos DB para asegurarse de que reacciona correctamente a diferentes condiciones de red. La aplicación debe tener reintentos en su lugar para los errores de tiempo de espera, ya que normalmente se esperan en un sistema distribuido.

Al evaluar el caso en caso de error por tiempo de espera:

  • ¿Qué impacto tiene el problema, si se mide comparando el volumen de operaciones afectadas con el de operaciones que sí se realizaron correctamente? ¿Es este valor aplicable a los Acuerdos de Nivel de Servicio?
  • ¿Se ve afectada la latencia o disponibilidad de P99?
  • ¿Afectan los errores a todas las instancias de la aplicación, o solo a un subconjunto? Si el problema se reduce a un subconjunto de instancias, normalmente se trata de un problema relacionado con ellas.

Personalización del tiempo de espera en el SDK de.NET para Azure Cosmos DB

El SDK tiene dos alternativas distintas a los tiempos de espera de control, cada una con un ámbito diferente.

Tiempos de espera de nivel de solicitud

La configuración CosmosClientOptions.RequestTimeout (o ConnectionPolicy.RequestTimeout para SDK v2) permite establecer un tiempo de espera para la solicitud de red después de que la solicitud deje el SDK y esté en la red, hasta que se reciba una respuesta.

La configuración CosmosClientOptions.OpenTcpConnectionTimeout (o ConnectionPolicy.OpenTcpConnectionTimeout para SDK v2) permite establecer un tiempo de espera para el tiempo dedicado a abrir una conexión inicial. Una vez abierta una conexión, las solicitudes posteriores usarán la conexión.

Una operación iniciada por un usuario puede abarcar varias solicitudes de red, como por ejemplo, reintentos. Estas dos configuraciones son por solicitud, no de un extremo a otro de una operación.

CancellationToken

Todas las operaciones asincrónicas del SDK tienen un parámetro CancellationToken opcional. Este parámetro CancellationToken se utiliza en toda la operación y en todas las solicitudes de red y reintentos. Entre las solicitudes de red, se puede comprobar el parámetro de cancelación. Una operación se cancela si el token relacionado ha expirado. El token de cancelación se debe usar para definir un tiempo de espera esperado aproximado en el ámbito de la operación.

Nota:

El parámetro CancellationToken es un mecanismo que permite a la biblioteca comprobar la cancelación cuando no cause un estado no válido. Es posible que la operación no se cancele exactamente cuando el tiempo definido en la cancelación esté activo. En su lugar, una vez que se agote el tiempo, se cancelará cuando sea seguro.

Pasos para solucionar problemas

La lista siguiente contiene las causas y las soluciones conocidas para las excepciones de tiempo de espera de solicitud.

CosmosOperationCanceledException

Este tipo de excepción es común cuando la aplicación pasa CancellationTokens a las operaciones del SDK. El SDK comprueba el estado de CancellationToken entre reintentos y, si CancellationToken se cancela, anulará la operación actual con esta excepción.

La excepción Message / ToString() también indicará el estado de CancellationToken a través de Cancellation Token has expired: true y contendrá diagnósticos con el contexto de la cancelación de las solicitudes implicadas.

Estas excepciones son seguras para reintentarlo y se pueden tratar como tiempos de espera desde la perspectiva del reintento.

Solución

Compruebe la hora configurada en CancellationToken, asegúrese de que es mayor que RequestTimeout y CosmosClientOptions.OpenTcpConnectionTimeout (si usa el modo directo). Si el tiempo disponible en CancellationToken es menor que los tiempos de espera configurados y el SDK tiene problemas de conectividad transitorios, el SDK no podrá reintentarlo y generará CosmosOperationCanceledException.

Uso elevado de CPU

El uso elevado de la CPU es el caso más común. Para lograr una latencia óptima, el uso de la CPU debe ser de aproximadamente el 40 por ciento. Use 10 segundos como intervalo para supervisar el uso máximo de la CPU (no el promedio). Los picos de CPU son más habituales con consultas entre particiones en las que se pueden realizar varias conexiones para una sola consulta.

Los tiempos de espera contienen Diagnósticos, que incluyen:

"systemHistory": [
{
"dateUtc": "2021-11-17T23:38:28.3115496Z",
"cpu": 16.731,
"memory": 9024120.000,
"threadInfo": {
"isThreadStarving": "False",
....
}

},
{
"dateUtc": "2021-11-17T23:38:28.3115496Z",
"cpu": 16.731,
"memory": 9024120.000,
"threadInfo": {
"isThreadStarving": "False",
....
}

},
...
]
  • Si los valores cpu superan el 70 %, es probable que el tiempo de estera se deba al agotamiento de la CPU. En este caso, la solución es investigar el origen del uso intensivo de la CPU y reducirlo, o bien escalar el equipo a un tamaño de recurso mayor.
  • Si los nodos threadInfo/isThreadStarving tienen valores True, la causa es el colapso de subprocesos. En este caso, la solución es investigar el origen u orígenes del colapso de subprocesos (subprocesos potencialmente bloqueados) o escalar los equipos a un tamaño de recurso mayor.
  • Si el tiempo dateUtc entre las medidas no es de aproximadamente 10 segundos, también indicaría que hay contención en el grupo de subprocesos. La CPU se mide como una tarea independiente que se pone en la cola en el grupo de subprocesos cada 10 segundos, si el tiempo entre las medidas es mayor, indicaría que las tareas asincrónicas no se pueden procesar de manera oportuna. Los escenarios más comunes son al bloquear llamadas a través de código asincrónico en el código de aplicación.

Solución

La aplicación cliente que usa el SDK se debe escalar vertical u horizontalmente.

La disponibilidad de puertos o de sockets puede ser reducida

Cuando se ejecutan en Azure, los clientes que usan el SDK de .NET pueden alcanzar el agotamiento de puertos SNAT (PAT) de Azure.

Solución 1

Si utiliza máquinas virtuales de Azure, siga la guía de agotamiento de los puertos SNAT.

Solución 2

Si utiliza Azure App Service, siga la guía de solución de problemas de errores de conexión y use el diagnóstico de App Service.

Solución 3

Si usa Azure Functions, compruebe que está siguiendo la recomendación para Azure Functions del mantenimiento de los clientes Singleton o estáticos para todos los servicios implicados (incluido Azure Cosmos DB). Compruebe los límites de servicio según el tipo y el tamaño del hospedaje de la aplicación de funciones.

Solución 4

Si usa un Proxy HTTP, asegúrese de que pueda admitir el número de conexiones configuradas en el SDK de ConnectionPolicy. En caso contrario, se encontrará con problemas de conexión.

Creación de varias instancias de cliente

La creación de varias instancias de cliente podría provocar problemas de tiempo de espera y la contención de la conexión. El diagnóstico contiene dos propiedades importantes:

{
    "NumberOfClientsCreated":X,
    "NumberOfActiveClients":Y,
}

NumberOfClientsCreated realiza un seguimiento del número de veces que se creó una instancia de CosmosClient en el mismo AppDomain y NumberOfActiveClients realiza un seguimiento de los clientes activos (no eliminados). La expectativa es que si se sigue el patrón singleton, X coincidiría con el número de cuentas con las que funciona la aplicación y que X es igual a Y.

Si X es mayor que Y, significa que la aplicación está creando y eliminando instancias de cliente. Esto puede provocar contención de la conexión o contención de CPU.

Solución

Siga los consejos de rendimiento y use una sola instancia de CosmosClient por cuenta en un proceso completo. Evite crear y eliminar clientes.

Clave de partición activa

Azure Cosmos DB distribuye el rendimiento general aprovisionado de forma uniforme entre las particiones físicas. Cuando hay una partición activa, una o varias claves de partición lógica en una partición física están consumiendo todas las unidades de solicitud de la partición física por segundo (RU/s). Al mismo tiempo, las RU/s de otras particiones físicas no se usan. Como síntoma, el total de RU/s consumido será inferior al total de RU/s aprovisionadas en la base de datos o el contenedor, pero seguirá viendo la limitación (429s) en las solicitudes de la clave de la partición lógica activa. Use la métrica de consumo normalizado de RU para ver si la carga de trabajo está detectando una partición activa.

Solución

Elija una buena clave de partición que distribuya uniformemente el volumen y el almacenamiento de solicitudes. Obtenga más información acerca de cómo cambiar la clave de partición.

Alto grado de simultaneidad

La aplicación tiene un alto nivel de simultaneidad, lo que puede provocar contención en el canal.

Solución

La aplicación cliente que usa el SDK se debe escalar vertical u horizontalmente.

Solicitudes o respuestas de gran tamaño

Un gran número de solicitudes o respuestas puede provocar un bloqueo de encabezado de línea en el canal y agravar la contención, incluso con un nivel relativamente bajo de simultaneidad.

Solución

La aplicación cliente que usa el SDK se debe escalar vertical u horizontalmente.

La tasa de errores está dentro del Acuerdo de Nivel de Servicio de Azure Cosmos DB

La aplicación debe ser capaz de controlar los errores transitorios y volver a intentarlo cuando sea necesario. Las excepciones 408 no se reintentan porque, en las rutas de acceso de creación, no es posible saber si el servicio creó el elemento. Si se vuelve a enviar el mismo elemento para crearlo, se producirá una excepción de conflicto. La lógica de negocios de las aplicaciones de usuario podría personalizarse para administrar los conflictos, lo que produciría errores por la ambigüedad de un elemento existente frente al conflicto de un reintento de creación.

La tasa de errores infringe el Acuerdo de Nivel de Servicio de Azure Cosmos DB

Póngase en contacto con el soporte técnico de Azure.

Pasos siguientes