Issue
I am using ActiveMQ Artemis 2.19.1 with the CORE Management API (org.apache.activemq.artemis.api.core.client.*
, and org.apache.activemq.artemis.api.core.management.*
) to get the consumer counts from some prefixed queues. If the counts are equal to zero there is something done in the back-end. This is done by a scheduled task which asks the broker periodically for this information.
For each request a temporary address is created under the hood and after consuming the info it is then deleted.
The problem is that the tree of the Artemis/Hawtio web console keeps refreshing making the UI sluggish and it's not maintainable. There is also a hint from Hawtio already regarding this behavior (see the subsection titled "The tree keeps refreshing making the UI sluggish").
As far as I know the CORE api is able to handle different nodes of a cluster which is way much more effort as with Jolokia. I think this was the main reason for using it.
Is there another possibility to handle this? Maybe some kind of connection/ session pooling? Or can the broker communicate with backend if the consumer count is zero? Or maybe the temporary queues could be deleted in a batch instead of each at a time?
This is what the logs say again and again:
[org.apache.activemq.artemis.core.server.plugin.impl] AMQ841007: created queue: QueueImpl[name=activemq.management.96a1005f-b67c-40af-b9cd-811f36750c5e, postOffice=PostOfficeImpl [server=ActiveMQServerImpl::name=artemis-2.19.1], temp=true]@58d1994e
[org.apache.activemq.artemis.core.server.plugin.impl] AMQ841008: destroyed queue: QueueImpl[name=activemq.management.96a1005f-b67c-40af-b9cd-811f36750c5e, postOffice=PostOfficeImpl [server=ActiveMQServerImpl::name=artemis-2.19.1], temp=true]@58d1994e, with args address: activemq.management.96a1005f-b67c-40af-b9cd-811f36750c5e, session: ServerSessionImpl(), checkConsumerCount: true, removeConsumers: false, autoDeleteAddress: true
For the connection I am using following:
private ServerLocator locator;
private ClientSessionFactory defaultFactory;
public ManagementHelper(String defaultURL) {
this.locator = ActiveMQClient.createServerLocator(defaultURL);
this.defaultFactory = locator.createSessionFactory();
}
@Scheduled(fixedRateString = "20000")
public void getConsumerNbos(ClientSessionFactory factory, ServerLocator locator) {
try (ClientSession session = factory.createSession(this.username, this.password, false, true, true,
locator.isPreAcknowledge(), locator.getAckBatchSize());
ClientRequestor requestor = new ClientRequestor(session, "activemq.management");) {
ClientMessage message = session.createMessage(false);
ManagementHelper.putOperationInvocation(message, ResourceNames.BROKER, listAllConsumersAsJSON);
session.start();
ClientMessage replyConsumer = requestor.request(message);
String resultJSON = (String) ManagementHelper.getResult(replyConsumer, String.class);
ClientMessage message2 = session.createMessage(false);
ManagementHelper.putOperationInvocation(message2, ResourceNames.BROKER, MANAGEMENT_OPERATION_QUEUES);
ClientMessage replyQueueNames = requestor.request(message2);
Object[] objQueueNames = (Object[]) ManagementHelper.getResult(replyQueueNames);
} catch (Exception e) {
}
}
Solution
To be clear, the log indicates that a queue is being created and destroyed, not an address.
The queue is being created an destroyed because you're using a org.apache.activemq.artemis.api.core.client.ClientRequestor
. When you create a ClientRequestor
it automatically creates a temporary queue named with a UUID on the address which you indicate (e.g. activemq.management
in your case). Then when you close the ClientRequestor
it deletes this queue.
My recommendation would be to simply cache your ClientSession
and your ClientRequestor
just like you do for your ServerLocator
and ClientSessionFactory
, e.g.:
private ServerLocator locator;
private ClientSessionFactory defaultFactory;
private ClientSession session;
private ClientRequestor requestor;
public ManagementHelper(String defaultURL) {
this.locator = ActiveMQClient.createServerLocator(defaultURL);
this.defaultFactory = locator.createSessionFactory();
this.session = factory.createSession(this.username, this.password, false, true, true, locator.isPreAcknowledge(), locator.getAckBatchSize());
this.requestor = new ClientRequestor(session, "activemq.management");
}
@Scheduled(fixedRateString = "20000")
public void getConsumerNbos(ClientSessionFactory factory, ServerLocator locator) {
ClientMessage message = session.createMessage(false);
ManagementHelper.putOperationInvocation(message, ResourceNames.BROKER, listAllConsumersAsJSON);
session.start();
ClientMessage replyConsumer = requestor.request(message);
String resultJSON = (String) ManagementHelper.getResult(replyConsumer, String.class);
ClientMessage message2 = session.createMessage(false);
ManagementHelper.putOperationInvocation(message2, ResourceNames.BROKER, MANAGEMENT_OPERATION_QUEUES);
ClientMessage replyQueueNames = requestor.request(message2);
Object[] objQueueNames = (Object[]) ManagementHelper.getResult(replyQueueNames);
}
If you are still having issues with the Hawtio refresh then you can also disable it by going to the "Preferences" page (in the top right of the web console) and clicking on the "Jolokia" tab and changing the "Update rate" to "Off". Here's a screenshot of the page:
Answered By - Justin Bertram
Answer Checked By - Terry (JavaFixing Volunteer)