Note
Access to this page requires authorization. You can try signing in or changing directories.
Access to this page requires authorization. You can try changing directories.
This article discusses how to modify an existing Java Message Service (JMS) 2.0 application that interacts with a JMS Broker to interact with Azure Service Bus instead. In particular, the article covers migrating from Apache ActiveMQ or Amazon MQ.
Azure Service Bus supports Java 2 Platform, Enterprise Edition and Spring workloads that use the JMS 2.0 API over Advanced Message Queueing Protocol (AMQP).
Azure Service Bus and Apache ActiveMQ are both message brokers, functioning as JMS providers for client applications to send messages to and receive messages from. They both enable the point-to-point semantics with queues, and publish-subscribe semantics with topics and subscriptions.
Even so, there are some differences between the two, as the following table shows:
Category | ActiveMQ | Azure Service Bus |
---|---|---|
Application tiering | Clustered monolith | Two-tier (gateway + back end) |
Protocol support |
|
AMQP |
Provisioning mode |
|
Managed platform as a service (PaaS) |
Message size | Customer configurable | 100 MB (Premium tier) |
High availability | Customer managed | Platform managed |
Disaster recovery | Customer managed | Platform managed |
The following table lists the Java Message Service (JMS) features that Azure Service Bus currently supports. It also shows features that are unsupported.
Feature | API | Status |
---|---|---|
Queues |
|
Supported |
Topics |
|
Supported |
Temporary queues |
|
Supported |
Temporary topics |
|
Supported |
Message Producer / JMSProducer |
|
Supported |
Queue browsers |
|
Supported |
Message Consumer/ JMSConsumer |
noLocal is currently not supported |
Supported |
Shared durable subscriptions |
|
Supported |
Unshared durable subscriptions |
noLocal is currently not supported and should be set to false |
Supported |
Shared non-durable subscriptions |
|
Supported |
Unshared non-durable subscriptions |
noLocal is currently not supported and should be set to false |
Supported |
Message selectors | depends on the consumer created | Supported |
Delivery Delay (scheduled messages) |
|
Supported |
Message created |
|
Supported |
Cross entity transactions |
|
Supported |
Distributed transactions | Not supported |
The two-tiered nature of Azure Service Bus affords various business continuity capabilities (high availability and disaster recovery). However, there are some considerations when you're using JMS features.
In case of service bus upgrades and restarts, temporary queues or topics are deleted. If your application is sensitive to data loss on temporary queues or topics, don't use temporary queues or topics. Use durable queues, topics, and subscriptions instead.
As part of migrating and modifying your client applications to interact with Azure Service Bus, the data held in ActiveMQ isn't migrated to Service Bus. You might need a custom application to drain the ActiveMQ queues, topics, and subscriptions, and then replay the messages to the queues, topics, and subscriptions of Service Bus.
Azure role-based access control (Azure RBAC), backed by Microsoft Entra ID, is the preferred authentication mechanism for Service Bus. To enable role-based access control, please follow the steps in the Azure Service Bus JMS 2.0 developer guide.
You use the following components and versions while you're writing the JMS applications:
Component | Version |
---|---|
Java Message Service (JMS) API | 1.1 or greater |
AMQP protocol | 1.0 |
Service Bus supports communication over the AMQP protocol. For this purpose, enable communication over ports 5671 (AMQP) and 443 (TCP). Depending on where the client applications are hosted, you might need a support ticket to allow communication over these ports.
Important
Service Bus supports only AMQP 1.0 protocol.
Service Bus enables various enterprise security and high availability features. For more information, see:
- Virtual network service endpoints
- Firewall
- Service side encryption with customer managed key (BYOK)
- Private endpoints
- Authentication and authorization
For each Service Bus namespace, you publish metrics onto Azure Monitor. You can use these metrics for alerting and dynamic scaling of resources allocated to the namespace.
For more information about the different metrics and how to set up alerts on them, see Service Bus metrics in Azure Monitor. You can also find out more about client side tracing for data operations and operational/diagnostic logging for management operations.
You can correlate which metrics from ActiveMQ map to which metrics in Azure Service Bus. See the following from the New Relic website:
Note
Currently, New Relic doesn't have direct, seamless integration with ActiveMQ, but they do have metrics available for Amazon MQ. Because Amazon MQ is derived from ActiveMQ, the following table maps the New Relic metrics from Amazon MQ to Azure Service Bus.
Metric grouping | Amazon MQ/ActiveMQ metric | Azure Service Bus metric |
---|---|---|
Broker | CpuUtilization |
CPUXNS |
Broker | MemoryUsage |
WSXNS |
Broker | CurrentConnectionsCount |
activeConnections |
Broker | EstablishedConnectionsCount |
activeConnections + connectionsClosed |
Broker | InactiveDurableTopicSubscribersCount |
Use subscription metrics |
Broker | TotalMessageCount |
Use queue/topic/subscription level activeMessages |
Queue/Topic | EnqueueCount |
incomingMessages |
Queue/Topic | DequeueCount |
outgoingMessages |
Queue | QueueSize |
sizeBytes |
To migrate your existing JMS 2.0 application to interact with Service Bus, follow the steps in the next several sections.
To ensure that client applications can seamlessly connect with Service Bus, migrate the topology (including queues, topics, and subscriptions) from Apache ActiveMQ to Service Bus.
Note
For JMS applications, you create queues, topics, and subscriptions as a runtime operation. Most JMS providers (message brokers) give you the ability to create these at runtime. That's why this export step is considered optional. To ensure that your application has the permissions to create the topology at runtime, use the connection string with SAS Manage
permissions.
To do this:
- Use the ActiveMQ command line tools to export the topology.
- Re-create the same topology by using an Azure Resource Manager template.
- Run the Azure Resource Manager template.
To ensure seamless connectivity with Service Bus, add the azure-servicebus-jms
package as a dependency to the Maven pom.xml
file, as follows:
<dependencies>
...
<dependency>
<groupId>com.microsoft.azure</groupId>
<artifactId>azure-servicebus-jms</artifactId>
</dependency>
...
</dependencies>
This part is customized to the application server that is hosting your client applications connecting to ActiveMQ.
If you're using a Spring boot application to connect to ActiveMQ, you want to remove the ActiveMQ-specific properties from the application.properties
file.
spring.activemq.broker-url=<ACTIVEMQ BROKER URL>
spring.activemq.user=<ACTIVEMQ USERNAME>
spring.activemq.password=<ACTIVEMQ PASSWORD>
Then, add the Service Bus-specific properties to the application.properties
file.
azure.servicebus.connection-string=Endpoint=myEndpoint;SharedAccessKeyName=mySharedAccessKeyName;SharedAccessKey=mySharedAccessKey
The next step is to replace the instance of ActiveMQConnectionFactory
with the ServiceBusJmsConnectionFactory
.
Note
The actual code changes are specific to the application and how dependencies are managed, but the following sample provides the guidance on what should be changed.
Previously, you might have been instantiating an object of ActiveMQConnectionFactory
, as follows:
String BROKER_URL = "<URL of the hosted ActiveMQ broker>";
ConnectionFactory factory = new ActiveMQConnectionFactory(BROKER_URL);
Connection connection = factory.createConnection();
connection.start();
Now, you're changing this to instantiate an object of ServiceBusJmsConnectionFactory
, as follows:
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();
Now that you have modified the application to start sending and receiving messages from Service Bus, you should verify that it works as you expect. When that's done, you can proceed to further refine and modernize your application stack.
To learn more about Service Bus messaging and JMS, see: