Compartir vía


Guía para la solución de problemas de Azure Service Bus

En este artículo se proporcionan sugerencias y recomendaciones para la solución de algunos problemas que pueden aparecer al usar Azure Service Bus.

Problemas de conectividad

Agotamiento del tiempo de espera al conectarse al servicio

Dependiendo del entorno del host y de la red, puede presentarse un problema de conectividad en las aplicaciones como TimeoutException, OperationCanceledException o ServiceBusException con Reason de ServiceTimeout, lo que ocurre con mayor frecuencia cuando el cliente no puede encontrar una ruta de acceso de red al servicio.

Para solucionar problemas:

Errores de protocolo de enlace de capa de sockets seguros (SSL)

Este error puede producirse cuando se usa un proxy de interceptación. Para comprobarlo, se recomienda probar la aplicación en el entorno host con el proxy deshabilitado.

Errores de agotamiento de sockets

Las aplicaciones deberían tratar preferentemente los tipos de Service Bus como bases de datos únicas, creando y usando una única instancia durante toda la vida útil de la aplicación. Cada nuevo ServiceBusClient creado da como resultado una nueva conexión AMQP, que usa un socket. El tipo ServiceBusClient administra la conexión para todos los tipos creados a partir de esa instancia. Cada ServiceBusReceiver, ServiceBusSessionReceiver, ServiceBusSendery ServiceBusProcessor administra su propio vínculo AMQP para la entidad de Service Bus asociada. Cuando se usa ServiceBusSessionProcessor, se establecen varios vínculos AMQP en función del número de sesiones que se procesan simultáneamente.

Los clientes son seguros para almacenar en caché cuando están inactivos; garantizarán una gestión eficaz del uso de la red, la CPU y la memoria, minimizando su efecto durante los períodos de inactividad. También es importante que se llame a CloseAsync o DisposeAsync cuando un cliente ya no sea necesario para garantizar que los recursos de red se limpien correctamente.

La adición de componentes a la cadena de conexión no funciona

La generación actual de la biblioteca cliente de Service Bus solo admite cadenas de conexión en el formulario publicado por Azure Portal. Las cadenas de conexión tienen por objetivo proporcionar únicamente información básica sobre la ubicación y las claves compartidas. La configuración del comportamiento de los clientes se realiza a través de sus opciones.

Las generaciones anteriores de los clientes de Service Bus permitían configurar algún comportamiento mediante la adición de componentes clave-valor a una cadena de conexión. Estos componentes ya no se reconocen y no tienen ningún efecto en el comportamiento del cliente.

Alternativa "TransportType=AmqpWebSockets"

Para configurar sockets web como tipo de transporte, consulte Configuración del transporte.

Alternativa "Authentication=Managed Identity"

Para autenticarse con la identidad administrada, consulte: Identidad y credenciales de acceso compartido. Para obtener más información sobre la biblioteca Azure.Identity, consulte Authentication and the Azure SDK (Autenticación y Azure SDK).

Registro y diagnóstico

La biblioteca cliente de Service Bus está totalmente instrumentada para registrar información en varios niveles de detalle mediante el EventSource de .NET para emitir información. El registro se realiza para cada operación y sigue el patrón de marcado del punto inicial de la operación, su finalización y las excepciones encontradas. La información adicional que podría ofrecer conclusiones también se registra en el contexto de la operación asociada.

Habilitar registro

Los registros de cliente de Service Bus están disponibles para cualquier EventListener mediante la participación en los orígenes que empiezan por Azure-Messaging-ServiceBus o mediante la participación en todos los orígenes con el rasgo AzureEventSource. Para facilitar la captura de registros de las bibliotecas cliente de Azure, la biblioteca Azure.Core usada por Service Bus ofrece un AzureEventSourceListener.

Para obtener más información, consulte Registro con Azure SDK para .NET.

Seguimiento distribuido

La biblioteca cliente de Service Bus admite el seguimiento distribuido mediante la integración con el SDK de Application Insights. También tiene compatibilidad experimental con la especificación OpenTelemetry mediante el tipo ActivitySource de .NET introducido en .NET 5. Para habilitar la compatibilidad con ActivitySource para su uso con OpenTelemetry, consulte Compatibilidad con ActivitySource.

Para usar la compatibilidad con DiagnosticActivity de GA, puede integrar con el SDK de Application Insights. Encontrará más información en ApplicationInsights con Azure Monitor.

La biblioteca crea los siguientes intervalos:

Message
ServiceBusSender.Send
ServiceBusSender.Schedule
ServiceBusSender.Cancel
ServiceBusReceiver.Receive
ServiceBusReceiver.ReceiveDeferred
ServiceBusReceiver.Peek
ServiceBusReceiver.Abandon
ServiceBusReceiver.Complete
ServiceBusReceiver.DeadLetter
ServiceBusReceiver.Defer
ServiceBusReceiver.RenewMessageLock
ServiceBusSessionReceiver.RenewSessionLock
ServiceBusSessionReceiver.GetSessionState
ServiceBusSessionReceiver.SetSessionState
ServiceBusProcessor.ProcessMessage
ServiceBusSessionProcessor.ProcessSessionMessage
ServiceBusRuleManager.CreateRule
ServiceBusRuleManager.DeleteRule
ServiceBusRuleManager.GetRules

La mayoría de los intervalos se explican por sí mismos y se inician y se detienen durante la operación que lleva su nombre. El intervalo que vincula a los demás es Message. El seguimiento del mensaje se realiza a través de Diagnostic-Id, que la biblioteca establece en la propiedad ServiceBusMessage.ApplicationProperties durante las operaciones de envío y programación. En Application Insights, los intervalos de Message se mostrarán como vinculados a los otros intervalos que se usaron para interactuar con el mensaje, por ejemplo, el intervalo de ServiceBusReceiver.Receive, el intervalo de ServiceBusSender.Send y el intervalo de ServiceBusReceiver.Complete se vincularían desde el intervalo de Message. Este es un ejemplo del aspecto que tendría en Application Insights:

Imagen que muestra un seguimiento distribuido de ejemplo.

En la captura de pantalla anterior, se observa la transacción de un extremo a otro que se puede ver en Application Insights en el portal. En este escenario, la aplicación envía mensajes y usa ServiceBusSessionProcessor para procesarlos. La actividad Message está vinculada a ServiceBusSender.Send, ServiceBusReceiver.Receive, ServiceBusSessionProcessor.ProcessSessionMessage y ServiceBusReceiver.Complete.

Solución de problemas del remitente

No se puede enviar un lote con varias claves de partición

Cuando una aplicación envía un lote a una entidad habilitada para particiones, todos los mensajes incluidos en una sola operación de envío deben tener la misma PartitionKey. Si la entidad está habilitada para la sesión, el mismo requisito es válido para la propiedad SessionId. Para enviar mensajes con valores de PartitionKey o SessionId diferentes, agrupe los mensajes en instancias de ServiceBusMessageBatch independientes o inclúyalos en llamadas independientes a la sobrecarga de SendMessagesAsync que toma un conjunto de instancias de ServiceBusMessage.

Error al enviar lote

Un lote de mensajes es un ServiceBusMessageBatch que contiene dos o más mensajes, o bien una llamada a SendMessagesAsync donde se pasan dos o más mensajes. El servicio no permite un valor superior a 1 MB para cada lote de mensajes. Este comportamiento es cierto tanto si la característica Premium de compatibilidad con mensajes grandes está activada como si no. Si piensa enviar un mensaje de un tamaño superior a 1 MB, debe enviarlo individualmente en lugar de agruparlo con otros mensajes. Desafortunadamente, el tipo ServiceBusMessageBatch no admite actualmente la validación de que un lote no contenga ningún mensaje superior a 1 MB, ya que el tamaño está limitado por el servicio y podría cambiar. Por lo tanto, si piensa usar la característica Premium de compatibilidad con mensajes grandes, deberá asegurarse de enviar los mensajes con tamaños superiores a 1 MB individualmente.

Solución de problemas del receptor

El número de mensajes devueltos no coincide con el número solicitado en la recepción por lotes

Al intentar realizar una operación de recepción por lotes, es decir, pasar un valor de maxMessages de dos o más al método ReceiveMessagesAsync, no se garantiza que se reciba el número de mensajes solicitados, ni siquiera aunque la cola o la suscripción tenga ese número de mensajes disponibles en ese momento, ni aunque no haya transcurrido aún todo el tiempo de maxWaitTime configurado. Para maximizar el rendimiento y evitar la expiración del bloqueo, una vez que el primer mensaje llega a través de la conexión, el receptor esperará 20 milisegundos más por cualquier mensaje adicional antes de enviar los mensajes para su procesamiento. El maxWaitTime controla cuánto tiempo esperará el receptor para recibir el primer mensaje: se esperará durante 20 milisegundos por los mensajes posteriores. Por lo tanto, la aplicación no debe suponer que todos los mensajes disponibles se recibirán en una sola llamada.

El bloqueo de mensaje o sesión se pierde antes del tiempo de expiración del bloqueo

El servicio Service Bus usa el protocolo AMQP, que es con estado. Debido a la naturaleza del protocolo, si el vínculo que conecta el cliente y el servicio se desasocia después de recibir un mensaje, pero antes de que se resuelva el mensaje, el mensaje no se puede resolver al volver a conectar el vínculo. Los vínculos se pueden desasociar debido a un error de red transitorio a corto plazo, una interrupción de la red o debido al tiempo de espera de inactividad de 10 minutos aplicado al servicio. La reconexión del vínculo se produce automáticamente como parte de cualquier operación que requiera el vínculo, es decir, establecer o recibir mensajes. En esta situación, recibirá una ServiceBusException con Reason de MessageLockLost o SessionLockLost incluso aunque no se haya superado el tiempo de expiración del bloqueo.

Cómo examinar mensajes programados o diferidos

Los mensajes programados y diferidos se incluyen al inspeccionar los mensajes. Se pueden identificar mediante la propiedad ServiceBusReceivedMessage.State. Una vez que tenga el SequenceNumber de un mensaje diferido, puede recibirlo con un bloqueo a través del método ReceiveDeferredMessagesAsync.

Al trabajar con temas, no se pueden inspeccionar los mensajes programados en la suscripción, ya que los mensajes permanecen en el tema hasta la hora de puesta en cola programada. Como solución alternativa, puede crear un ServiceBusReceiver pasando el nombre del tema para inspeccionar dichos mensajes. Ninguna otra operación con el receptor funcionará al usar un nombre de tema.

Cómo examinar los mensajes de sesión en todas las sesiones

Puede usar un ServiceBusReceiver normal para inspeccionar en todas las sesiones. Para inspeccionar una sesión específica, puede usar el ServiceBusSessionReceiver, pero tendrá que obtener un bloqueo de sesión.

NotSupportedException se genera al acceder al cuerpo del mensaje

Este problema se produce con más frecuencia en escenarios de interoperabilidad al recibir un mensaje enviado desde una biblioteca diferente que usa un formato de cuerpo del mensaje AMQP diferente. Si está interactuando con estos tipos de mensajes, consulte el ejemplo de cuerpo de mensaje AMQP para obtener información sobre cómo acceder al cuerpo del mensaje.

Solución de problemas de procesador

La renovación del bloqueo automático no funciona

La renovación de bloqueo automático depende de la hora del sistema para determinar cuándo renovar un bloqueo para un mensaje o una sesión. Si la hora del sistema no es precisa, por ejemplo, el reloj es lento, es posible que se pierda el bloqueo antes de que se produzca la renovación. Si la renovación del bloqueo automático no funciona, compruebe si la hora de su sistema es la correcta.

Parece que el procesador se bloquea o tiene problemas de latencia al usar una alta simultaneidad

Este comportamiento suele deberse a un colapso de subprocesos, en particular cuando se usa el procesador de sesiones y un valor muy alto para MaxConcurrentSessions con respecto al número de núcleos de la máquina. Lo primero que habría que hacer es asegurarse de que no se esté usando el enfoque sincrónico sobre asincrónico en ninguno de los controladores de eventos. El enfoque sincrónico sobre asincrónico puede causar interbloqueos y colapsar subprocesos muy fácilmente. Incluso aunque no se use el enfoque sincrónico sobre asincrónico, cualquier código sincrónico puro en los controladores podría contribuir al colapso de los subprocesos. Si ha determinado que ese no es el problema, por ejemplo, porque tiene código asincrónico puro, puede intentar aumentar el valor TryTimeout. Esto aliviará la presión sobre el grupo de subprocesos mediante la reducción del número de cambios de contexto y tiempos de espera que se producen al usar el procesador de sesiones en particular. El valor predeterminado de TryTimeout es de 60 segundos, pero se puede establecer hasta en un máximo de una hora. Se recomienda realizar pruebas con el TryTimeout establecido en 5 minutos como punto de partida e iterar desde ahí. Si ninguna de estas sugerencias funciona, basta con escalar horizontalmente a varios hosts, lo que reduce la simultaneidad en la aplicación, pero ejecuta la aplicación en varios hosts para lograr la simultaneidad general deseada.

Lecturas adicionales:

El procesador de sesiones tarda demasiado tiempo en cambiar de sesión

Esto se puede configurar mediante SessionIdleTimeout, que indica al procesador cuánto tiempo debe esperar para recibir un mensaje de una sesión, antes de abandonar y pasar a otra. Esto resulta útil si se tienen muchas sesiones rellenadas dispersamente, donde cada sesión solo tiene algunos mensajes. Si espera que en cada sesión entren muchos mensajes, establecer un valor demasiado bajo puede ser contraproducente, ya que provocará un cierre innecesario de la sesión.

El procesador se detiene de inmediato

Esto suele producirse en los escenarios de demostración o pruebas. StartProcessingAsync se devuelve inmediatamente tras iniciarse el procesador. Llamar a este método no producirá bloqueos y mantendrá activa la aplicación mientras se ejecuta el procesador, por lo que necesitará algún otro mecanismo para hacerlo. Para demostraciones o pruebas, basta con agregar una llamada a Console.ReadKey() después de iniciar el procesador. En escenarios de producción, es probable que quiera usar algún tipo de integración de marcos como BackgroundService para proporcionar enlaces convenientes del ciclo de vida de la aplicación que se pueden usar para iniciar y eliminar el procesador.

Solución de problemas de transacciones

Para obtener información general sobre las transacciones en Service Bus, vea Información general sobre el procesamiento de transacciones de Service Bus.

Operaciones compatibles

No todas las operaciones se admiten al usar transacciones. Para obtener la lista de transacciones admitidas, vea Operaciones dentro de un ámbito de transacción.

Tiempo de espera

El tiempo de espera de una transacción se agota después de un período de tiempo, por lo que es importante que el procesamiento que se produce en un ámbito de transacción cumpla este tiempo de espera.

Las operaciones de una transacción no se reintentan

es así por diseño. Considere el siguiente escenario: está intentando completar un mensaje en una transacción, pero se produce algún error transitorio, por ejemplo, ServiceBusException con Reason de ServiceCommunicationProblem. Supongamos que la solicitud acaba llegando al servicio. Si el cliente volviera a intentarlo, el servicio vería dos solicitudes completas. La primera solicitud completa no se finalizará hasta que se confirme la transacción. La segunda solicitud completa ni siquiera puede evaluarse hasta que finalice la primera. La transacción en el cliente está esperando a que finalice la operación. Esto crea un interbloqueo en el que el servicio está esperando a que el cliente complete la transacción, pero el cliente está esperando a que el servicio confirme la segunda operación completa. El tiempo de espera de la transacción se agotará tras 2 minutos, pero se trata de una mala experiencia de usuario. Por este motivo, no se reintentan las operaciones dentro de una transacción.

Las transacciones entre entidades no funcionan.

Para realizar transacciones que implican varias entidades, debe establecer la propiedad ServiceBusClientOptions.EnableCrossEntityTransactions en true. Para obtener los detalles, vea el ejemplo Transacciones entre entidades.

Cuotas

Aquí encontrará información sobre las cuotas de Service Bus.

Problemas de conectividad, certificados o tiempo de espera

Los pasos siguientes le ayudarán a solucionar problemas de conectividad, certificados y tiempo de espera de todos los servicios de *.servicebus.windows.net.

  • Desplácese a https://<yournamespace>.servicebus.windows.net/ o use wget ir allí. Le permite comprobar si tiene problemas con la cadena de certificados, el filtrado IP o la red virtual, lo que suele ser común al usar el SDK de Java.

    Un ejemplo de mensaje correcto:

    <feed xmlns="http://www.w3.org/2005/Atom"><title type="text">Publicly Listed Services</title><subtitle type="text">This is the list of publicly-listed services currently available.</subtitle><id>uuid:27fcd1e2-3a99-44b1-8f1e-3e92b52f0171;id=30</id><updated>2019-12-27T13:11:47Z</updated><generator>Service Bus 1.1</generator></feed>
    

    Un ejemplo de mensaje de error:

    <Error>
        <Code>400</Code>
        <Detail>
            Bad Request. To know more visit https://aka.ms/sbResourceMgrExceptions. . TrackingId:b786d4d1-cbaf-47a8-a3d1-be689cda2a98_G22, SystemTracker:NoSystemTracker, Timestamp:2019-12-27T13:12:40
        </Detail>
    </Error>
    
  • Ejecute el siguiente comando para comprobar si hay algún puerto bloqueado en el firewall. Los puertos empleados son 443 (HTTPS), 5671 y 5672 (AMQP) y 9354 (mensajería .NET o SBMP). En función de la biblioteca que use, también se usan otros puertos. Este es el comando de ejemplo que comprueba si el puerto 5671 está bloqueado. C

    tnc <yournamespacename>.servicebus.windows.net -port 5671
    

    En Linux:

    telnet <yournamespacename>.servicebus.windows.net 5671
    
  • Si hay problemas de conectividad intermitentes, ejecute el siguiente comando para comprobar si hay paquetes descartados. Este comando intenta establecer 25 conexiones TCP diferentes cada segundo con el servicio. A continuación, puede comprobar cuántas de ellas se han realizado correctamente y cuántas han fallado y, además, ver la latencia de conexión TCP. Puede descargar la herramienta psping desde psping.

    .\psping.exe -n 25 -i 1 -q <yournamespace>.servicebus.windows.net:5671 -nobanner     
    

    Puede usar comandos equivalentes si utiliza otras herramientas como tnc, ping, etc.

  • Realice un seguimiento de red si los pasos anteriores no ayudan y analícelo con herramientas como Wireshark. Si lo necesita, póngase en contacto con el soporte técnico de Microsoft.

  • Para buscar las direcciones IP correctas que se van a agregar a la lista de conexiones permitidas, consulte ¿Qué direcciones IP debo agregar a la lista de permitidas?

El 30 de septiembre de 2026, retiraremos el soporte técnico del protocolo SBMP para Azure Service Bus, por lo que ya no podrá usar este protocolo después del 30 de septiembre de 2026. Migre a las bibliotecas más recientes del SDK de Azure Service Bus mediante el protocolo AMQP, que ofrecen actualizaciones de seguridad críticas y funcionalidades mejoradas, antes de esa fecha.

Para obtener más información, consulte el anuncio de retirada de soporte técnico.

Problemas que se pueden producir con las actualizaciones o reinicios de servicios

Síntomas

  • Puede que las solicitudes se limiten momentáneamente.
  • Puede haber una caída en la llegada de mensajes o solicitudes entrantes.
  • El archivo de registro puede contener mensajes de error.
  • Puede que las aplicaciones se desconecten del servicio durante unos segundos.

Causa

Las actualizaciones y los reinicios de servicios back-end pueden provocar estos problemas en las aplicaciones.

Solución

Si el código de aplicación usa el SDK, la directiva de reintentos ya está integrada y activa. La aplicación se vuelve a conectar sin un impacto significativo en la aplicación o el flujo de trabajo.

Acceso no autorizado: las notificaciones de envío son necesarias

Síntomas

Es posible que vea este error al intentar obtener acceso a un tema de Service Bus desde Visual Studio en un equipo local mediante una identidad administrada asignada por el usuario con permisos de envío.

Service Bus Error: Unauthorized access. 'Send' claim\(s\) are required to perform this operation.

Causa

La identidad no tiene permisos de acceso al tema de Service Bus.

Resolución

Para resolverlo, instale la biblioteca Microsoft.Azure.Services.AppAuthentication. Par obtener más información, consulte Autenticación de desarrollo local.

Para obtener información sobre cómo asignar permisos a los roles, consulte Autenticación de una identidad administrada con Microsoft Entra ID para acceder a recursos de Azure Service Bus.

Excepción de Service Bus: error al colocar el token

Síntomas

Aparece el siguiente mensaje de error:

Microsoft.Azure.ServiceBus.ServiceBusException: Put token failed. status-code: 403, status-description: The maximum number of '1000' tokens per connection has been reached.

El 30 de septiembre de 2026, retiraremos las bibliotecas del SDK de Azure Service Bus WindowsAzure.ServiceBus, Microsoft.Azure.ServiceBus y com.microsoft.azure.servicebus, que no se ajustan a las directrices del SDK de Azure. También retiraremos el soporte del protocolo SBMP, por lo que ya no podrás usar este protocolo después del 30 de septiembre de 2026. Migre a las bibliotecas más recientes del SDK de Azure, que ofrecen actualizaciones de seguridad críticas y funcionalidades mejoradas, antes de esa fecha.

Aunque las bibliotecas anteriores todavía se pueden usar después del 30 de septiembre de 2026, ya no recibirán soporte técnico oficial ni actualizaciones de Microsoft. Para obtener más información, consulte el anuncio de retirada de soporte técnico.

Causa

El número de tokens de autenticación para vínculos simultáneos en una sola conexión a un espacio de nombres de Service Bus ha superado el límite: 1000.

Solución

Realice uno de los siguientes pasos:

  • Reduzca el número de vínculos simultáneos en una sola conexión o use una nueva conexión
  • Use los SDK para Azure Service Bus para evitar esta situación (recomendado)

Los bloqueos de recursos no funcionan al usar el SDK del plano de datos

Síntomas

Ha configurado un bloqueo de eliminación en un espacio de nombres de Service Bus, pero puede eliminar recursos en el espacio de nombres (colas, temas, etc.) mediante Service Bus Explorer.

Causa

El bloqueo de recursos se conserva en Azure Resource Manager (plano de control) y no impide que la llamada del SDK del plano de datos elimine el recurso directamente desde el espacio de nombres. Service Bus Explorer independiente usa el SDK del plano de datos, por lo que la eliminación pasa.

Resolución

Se recomienda usar la API basada en Azure Resource Manager a través de Azure Portal, PowerShell, la CLI o la plantilla de Resource Manager para eliminar entidades de forma que el bloqueo de recursos impida que los recursos se eliminen accidentalmente.

La entidad ya no está disponible

Síntomas

Verá un error que indica que la entidad ya no está disponible.

Causa

Puede que se haya eliminado el recurso. Siga estos pasos para identificar por qué se eliminó la entidad.

  • Compruebe el registro de actividad para ver si hay alguna solicitud de eliminación de Azure Resource Manager.
  • Compruebe el registro operativo para ver si se ha producido una llamada de API directa para su eliminación. Para obtener información sobre cómo recopilar un registro operativo, vea Monitor Azure Service Bus. Para obtener el esquema y un ejemplo de un registro de operaciones, consulte Registros de operaciones
  • Compruebe el registro de operaciones para ver si se ha producido una eliminación autodeleteonidle relacionada.

Pasos siguientes

Vea los artículos siguientes: