Migración de aplicaciones de Java Message Service (JMS) 2.0 de Apache ActiveMQ a Azure Service Bus

En este artículo se explica cómo modificar una aplicación de Java Message Service (JMS) 2.0 existente que interactúa con un agente de JMS para que interactúe con Azure Service Bus en su lugar. En concreto, en el artículo se trata la migración de Apache ActiveMQ o Amazon MQ.

Azure Service Bus admite cargas de trabajo de Java 2 Platform, Enterprise Edition y Spring que usan la API de JMS 2.0 en el protocolo Advanced Message Queuing Protocol (AMQP).

Antes de comenzar

Diferencias entre Azure Service Bus y Apache ActiveMQ

Tanto Azure Service Bus como Apache ActiveMQ son agentes de mensajes que funcionan como proveedores de JMS para que las aplicaciones del cliente envíen y reciban mensajes. Ambos agentes permiten la semántica punto a punto con colas y la semántica de publicación-suscripción con temas y suscripciones.

Aun así, hay varias diferencias entre ambos, tal como se muestra en la tabla siguiente:

Category ActiveMQ Azure Service Bus
Aplicación por niveles Monolito en clúster Dos niveles
(puerta de enlace + back end)
Compatibilidad con protocolos
  • AMQP
  • STOMP
  • OpenWire
AMQP
Modo de aprovisionamiento
  • Infraestructura como servicio (IaaS), local
  • Amazon MQ (plataforma administrada como servicio)
Plataforma administrada como servicio (PaaS)
Tamaño del mensaje Configurable por el usuario 100 MB (nivel Premium)
Alta disponibilidad Administrado por el cliente Administrado por plataforma
Recuperación ante desastres Administrado por el cliente Administrado por plataforma

Características admitidas y no admitidas actualmente

En la tabla siguiente se enumeran las características de Java Message Service (JMS) que Azure Service Bus admite actualmente. También se muestran las características que no son compatibles.

Característica API Estado
Colas
  • JMSContext.createQueue( String queueName)
Compatible
Temas
  • JMSContext.createTopic( String topicName)
Compatible
Colas temporales
  • JMSContext.createTemporaryQueue()
Compatible
Temas temporales
  • JMSContext.createTemporaryTopic()
Compatible
Productor de mensajes /
JMSProducer
  • JMSContext.createProducer()
Compatible
Exploradores de colas
  • JMSContext.createBrowser(Queue queue)
  • JMSContext.createBrowser(Queue queue, String messageSelector)
Compatible
Consumidor de mensajes/
JMSConsumer
  • JMSContext.createConsumer( Destination destination)
  • JMSContext.createConsumer( Destination destination, String messageSelector)
  • JMSContext.createConsumer( Destination destination, String messageSelector, boolean noLocal)

Actualmente, noLocal no se admite.
Compatible
Suscripciones duraderas compartidas
  • JMSContext.createSharedDurableConsumer(Topic topic, String name)
  • JMSContext.createSharedDurableConsumer(Topic topic, String name, String messageSelector)
Compatible
Suscripciones duraderas no compartidas
  • JMSContext.createDurableConsumer(Topic topic, String name)
  • createDurableConsumer(Topic topic, String name, String messageSelector, boolean noLocal)

Actualmente no se admite noLocal y debe establecerse en false.
Compatible
Suscripciones no duraderas compartidas
  • JMSContext.createSharedConsumer(Topic topic, String sharedSubscriptionName)
  • JMSContext.createSharedConsumer(Topic topic, String sharedSubscriptionName, String messageSelector)
Compatible
Suscripciones no duraderas no compartidas
  • JMSContext.createConsumer(Destination destination)
  • JMSContext.createConsumer( Destination destination, String messageSelector)
  • JMSContext.createConsumer( Destination destination, String messageSelector, boolean noLocal)

Actualmente no se admite noLocal y debe establecerse en false.
Compatible
Selectores de mensajes dependen del consumidor creado Compatible
Retraso de la entrega (mensajes programados)
  • JMSProducer.setDeliveryDelay( long deliveryDelay)
Compatible
Mensaje creado
  • JMSContext.createMessage()
  • JMSContext.createBytesMessage()
  • JMSContext.createMapMessage()
  • JMSContext.createObjectMessage( Serializable object)
  • JMSContext.createStreamMessage()
  • JMSContext.createTextMessage()
  • JMSContext.createTextMessage( String text)
Compatible
Transacciones entre entidades
  • Connection.createSession(true, Session.SESSION_TRANSACTED)
Compatible
Distributed transactions No compatibles

Consideraciones

La naturaleza de dos niveles de Azure Service Bus ofrece diversas funcionalidades de continuidad del negocio (alta disponibilidad y recuperación ante desastres). Sin embargo, cuando se usan las características de JMS es preciso tener en cuenta varias consideraciones.

Actualizaciones del servicio

En el caso de las actualizaciones y los reinicios de Service Bus, se eliminan las colas o los temas temporales. Si su aplicación es sensible a la pérdida de datos en colas o temas temporales, no utilice colas ni temas temporales. Use colas, temas y suscripciones duraderas en su lugar.

Migración de datos

Como parte de la migración y modificación de las aplicaciones cliente para interactuar con Azure Service Bus, los datos que se conservan en ActiveMQ no se migran a Service Bus. Es posible que necesite una aplicación personalizada para purgar las colas, los temas y las suscripciones de ActiveMQ y, posteriormente, reproducir los mensajes en las colas, los temas y las suscripciones de Service Bus.

Autenticación y autorización

El control de acceso basado en rol de Azure (RBAC de Azure) respaldado por Microsoft Entra ID es el mecanismo de autenticación preferido para Service Bus. Para habilitar el control de acceso basado en rol, siga los pasos descritos en la Guía del desarrollador de JMS 2.0 para Azure Service Bus.

Antes de la migración

Comprobación de versión

Puede usar los siguientes componentes y versiones mientras escribe las aplicaciones de JMS:

Componente Versión
API de Java Message Service (JMS) 1.1 o superior
Protocolo AMQP 1.0

Asegúrese de que los puertos AMQP estén abiertos.

Service Bus admite la comunicación a través del protocolo AMQP. Para ello, habilite la comunicación a través de los puertos 5671 (AMQP) y 443 (TCP). Según dónde se hospeden las aplicaciones cliente, es posible que necesite abrir una incidencia de soporte técnico para permitir la comunicación a través de estos puertos.

Importante

Service Bus solo admite el protocolo AMQP 1.0.

Realización de configuraciones empresariales

Service Bus habilita diversas características de seguridad y alta disponibilidad de la empresa. Para más información, consulte:

Supervisión, alertas y seguimiento

Para todos los espacios de nombres de Service Bus, publique las métricas en Azure Monitor. Estas métricas se pueden usar no solo para la generación de alertas, sino también para el escalado dinámico de los recursos asignados al espacio de nombres.

Para más información sobre las diferentes métricas y cómo configurar alertas en ellas, consulte Métricas de Service Bus en Azure Monitor. También puede obtener más información sobre el seguimiento del lado del cliente para las operaciones de datos y el registro operativo o de diagnóstico para las operaciones de administración.

Métricas: New Relic

Puede correlacionar qué métricas de ActiveMQ se asignan a las métricas de Azure Service Bus. Consulte lo siguiente en el sitio web de New Relic:

Nota

Actualmente, New Relic no tiene una integración directa perfecta con ActiveMQ, pero tiene métricas disponibles para Amazon MQ. Como Amazon MQ se deriva de ActiveMQ, la tabla siguiente asigna las métricas de New Relic de Amazon MQ a Azure Service Bus.

Agrupación de métricas Métrica de Amazon MQ/ActiveMQ Métricas de Azure Service Bus
Agente CpuUtilization CPUXNS
Agente MemoryUsage WSXNS
Agente CurrentConnectionsCount activeConnections
Agente EstablishedConnectionsCount activeConnections + connectionsClosed
Agente InactiveDurableTopicSubscribersCount Uso de métricas de suscripción
Agente TotalMessageCount Uso del nivel de cola, tema o suscripción activeMessages
Cola o tema EnqueueCount incomingMessages
Cola o tema DequeueCount outgoingMessages
Cola QueueSize sizeBytes

Migración

Para migrar una aplicación de JMS 2.0 existente para interactuar con Service Bus, siga los pasos que se indican en las siguientes secciones.

Exportación de la topología de ActiveMQ y creación de las entidades en Service Bus (opcional)

Para asegurarse de que las aplicaciones cliente pueden conectarse sin problemas con Service Bus, migre la topología (que incluye colas, temas y suscripciones) desde Apache ActiveMQ a Service Bus.

Nota

En el caso de las aplicaciones de JMS, cree las colas, los temas y las suscripciones como una operación en tiempo de ejecución. La mayoría de los proveedores de JMS (agentes de mensajes) brindan la posibilidad de crearlos en tiempo de ejecución. Ese es el motivo por el que este paso de exportación se considera opcional. Para asegurarse de que la aplicación tiene los permisos necesarios para crear la topología en tiempo de ejecución, use la cadena de conexión con permisos de SAS Manage.

Para ello, siga estos pasos:

  1. Use las herramientas de la línea de comandos de ActiveMQ para exportar la topología.
  2. Vuelva a crear la misma topología mediante una plantilla de Azure Resource Manager.
  3. Ejecute la plantilla de Azure Resource Manager.

Importe la dependencia de Maven para la implementación de Service Bus JMS.

Para garantizar una conectividad sin problemas con Service Bus, agregue el paquete azure-servicebus-jms como una dependencia al archivo pom.xml de Maven, como se indica a continuación:

<dependencies>
...
    <dependency>
        <groupId>com.microsoft.azure</groupId>
        <artifactId>azure-servicebus-jms</artifactId>
    </dependency>
...
</dependencies>

Cambios en la configuración del servidor de aplicaciones

Esta parte está personalizada para el servidor de aplicaciones que hospeda las aplicaciones cliente que se conectan a ActiveMQ.

Aplicaciones de spring

Actualización del archivo application.properties

Si va a usar una aplicación de Spring Boot para conectarse a ActiveMQ, quite las propiedades específicas de ActiveMQ del archivo de application.properties.

spring.activemq.broker-url=<ACTIVEMQ BROKER URL>
spring.activemq.user=<ACTIVEMQ USERNAME>
spring.activemq.password=<ACTIVEMQ PASSWORD>

Luego, agregue las propiedades específicas de Service Bus al archivo application.properties.

azure.servicebus.connection-string=Endpoint=myEndpoint;SharedAccessKeyName=mySharedAccessKeyName;SharedAccessKey=mySharedAccessKey
Reemplazar ActiveMQConnectionFactory con ServiceBusJmsConnectionFactory

El siguiente paso es reemplazar la instancia de ActiveMQConnectionFactory por la de ServiceBusJmsConnectionFactory.

Nota

Los cambios de código reales son específicos de la aplicación y de la forma en que administran las dependencias, pero en el ejemplo siguiente se proporciona una guía para saber lo que no se debe cambiar.

Anteriormente, es posible que haya creado una instancia de un objeto de ActiveMQConnectionFactory como se indica a continuación:


String BROKER_URL = "<URL of the hosted ActiveMQ broker>";
ConnectionFactory factory = new ActiveMQConnectionFactory(BROKER_URL);

Connection connection = factory.createConnection();
connection.start();

Ahora, va a cambiarlo y va a crear una instancia de un objeto de ServiceBusJmsConnectionFactory como se indica a continuación:


ServiceBusJmsConnectionFactorySettings settings = new ServiceBusJmsConnectionFactorySettings();
String SERVICE_BUS_CONNECTION_STRING = "<Service Bus Connection string>";

ConnectionFactory factory = new ServiceBusJmsConnectionFactory(SERVICE_BUS_CONNECTION_STRING, settings);

Connection connection = factory.createConnection();
connection.start();

Después de la migración

Ahora que ha modificado la aplicación para empezar a enviar y recibir mensajes desde Service Bus, debe comprobar que funciona como cabría esperar. Cuando haya finalizado, puede continuar para refinar y modernizar aún más la pila de aplicaciones.

Pasos siguientes

Use Spring Boot Starter para JMS en Azure Service Bus para lograr una integración sin problemas con Service Bus.

Para más información sobre la mensajería y JMS de Service Bus, consulte: