[
https://issues.apache.org/jira/browse/ARTEMIS-3424?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=17401261#comment-17401261
]
Justin Bertram commented on ARTEMIS-3424:
-----------------------------------------
The {{DEBUG}} logging here is the result of a known race condition between core
JMS clients which are auto-creating destinations. In your code when both
consumers are started concurrently each checks for the existence of the
destination and both are informed that the destination doesn't exist. Therefore
each consumer attempts to create the destination. One succeeds and one fails.
However, the consumer which fails simply ignores the exception as it is a
{{ActiveMQQueueExistsException}} since that means the queue it is trying to
create already exists which is functionally equivalent to successfully creating
the queue.
The broker logs the exception just like any other exception because it doesn't
necessarily know the client will ignore the exception. This is different from
ARTEMIS-1707 because in that situation the exception could be ignored _on the
broker_ which isn't true here.
It's also worth noting that debug logging, generally speaking, is expected to
be used by folks who have a fairly decent grasp of how the broker works
internally (e.g. developers working to diagnose an issue). Exceptions logged at
debug can be safely ignored and are presented for informational purposes only.
Actual problems are logged at {{WARN}} or {{ERROR}}.
> Unnecessary exception "ActiveMQQueueExistsException: Binding already exists
> LocalQueueBinding" when creating queue consumers
> ----------------------------------------------------------------------------------------------------------------------------
>
> Key: ARTEMIS-3424
> URL: https://issues.apache.org/jira/browse/ARTEMIS-3424
> Project: ActiveMQ Artemis
> Issue Type: Improvement
> Reporter: Endre Stølsvik
> Priority: Minor
>
> While working with embedded Artemis (employing the in-vm acceptor), I found
> these worrisome debug exceptions that consistently came up:
> {{ActiveMQQueueExistsException: AMQ229018: Binding already exists
> LocalQueueBinding [address=Test.queue...]}}
> After having scratched my head for a good while, it occurred to me to check
> on a default install of an Artemis broker on command line, after having
> adjusted the logging. And lo and behold, they also appear there.
>
> {code:java}
> 2021-08-18 17:39:22,936 DEBUG
> [org.apache.activemq.artemis.core.protocol.core.ServerSessionPacketHandler]
> Sending exception to client:
> ActiveMQQueueExistsException[errorType=QUEUE_EXISTS message=AMQ229018:
> Binding already exists LocalQueueBinding [address=Test.queue,
> queue=QueueImpl[name=Test.queue, postOffice=PostOfficeImpl
> [server=ActiveMQServerImpl::serverUUID=abc2a8cb-f37b-11eb-bfbc-60f2623f9c33],
> temp=false]@7ad901eb, filter=null, name=Test.queue,
> clusterName=Test.queueabc2a8cb-f37b-11eb-bfbc-60f2623f9c33]]
> at
> org.apache.activemq.artemis.core.postoffice.impl.SimpleAddressManager.addBinding(SimpleAddressManager.java:91)
> [artemis-server-2.17.0.jar:2.17.0]
> at
> org.apache.activemq.artemis.core.postoffice.impl.WildcardAddressManager.addBinding(WildcardAddressManager.java:95)
> [artemis-server-2.17.0.jar:2.17.0]
> at
> org.apache.activemq.artemis.core.postoffice.impl.PostOfficeImpl.addBinding(PostOfficeImpl.java:873)
> [artemis-server-2.17.0.jar:2.17.0]
> ...
> {code}
> To me, this seems like just noise of the type that makes you wonder, even
> though they are emitted on debug.
> It seems like a similar situation have been tackled earlier, in ARTEMIS-1707,
> but that was ActiveMQAddressExistsException, while this is
> ActiveMQQueueExistsException.
> Here's a class that exhibits the situation. Note that it evidently works just
> fine, both of the consumers receiving exactly half of the messages:
>
> {code:java}
> import java.util.concurrent.CountDownLatch;
> import java.util.concurrent.TimeUnit;
> import javax.jms.Connection;
> import javax.jms.Message;
> import javax.jms.MessageConsumer;
> import javax.jms.MessageProducer;
> import javax.jms.Queue;
> import javax.jms.Session;
> import javax.jms.TextMessage;
> import org.apache.activemq.artemis.api.core.QueueConfiguration;
> import org.apache.activemq.artemis.api.core.RoutingType;
> import org.apache.activemq.artemis.api.core.SimpleString;
> import org.apache.activemq.artemis.core.config.Configuration;
> import org.apache.activemq.artemis.core.config.CoreAddressConfiguration;
> import org.apache.activemq.artemis.core.config.impl.ConfigurationImpl;
> import org.apache.activemq.artemis.core.server.embedded.EmbeddedActiveMQ;
> import org.apache.activemq.artemis.core.settings.impl.AddressSettings;
> import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory;
> public class Test_MatsTestBroker {
> // @Test
> public void test() throws Exception {
> String brokerUrl = "vm://test";
> // String brokerUrl = "tcp://localhost:61616";
> EmbeddedActiveMQ broker = brokerUrl.startsWith("vm")
> ? createArtemisBroker(brokerUrl)
> : null;
> ActiveMQConnectionFactory connectionFactory = new
> ActiveMQConnectionFactory(brokerUrl);
> Connection connection = connectionFactory.createConnection();
> int numberOfMessages = 50;
> CountDownLatch countDownLatch = new CountDownLatch(numberOfMessages);
> Thread thread1 = new Thread(() -> consumer(connection,
> countDownLatch), "EndreXY 1");
> Thread thread2 = new Thread(() -> consumer(connection,
> countDownLatch), "EndreXY 2");
> thread1.start();
> thread2.start();
> connection.start();
> Session session = connection.createSession(false,
> Session.AUTO_ACKNOWLEDGE);
> Queue queue = session.createQueue("Test.queue");
> MessageProducer producer = session.createProducer(queue);
> for (int i = 0; i < 50; i++) {
> TextMessage textMessage = session.createTextMessage("Message " +
> i);
> producer.send(textMessage);
> }
> boolean await = countDownLatch.await(10, TimeUnit.SECONDS);
> // Assert.assertTrue("Counted down correctly, received all messages",
> await);
> connection.close();
> if (broker != null) {
> broker.stop();
> }
> }
> private void consumer(Connection con, CountDownLatch countDownLatch) {
> try {
> Session session = con.createSession(false,
> Session.AUTO_ACKNOWLEDGE);
> Queue queue = session.createQueue("Test.queue");
> MessageConsumer consumer = session.createConsumer(queue);
> while (true) {
> Message msg = consumer.receive(10_000);
> countDownLatch.countDown();
> if (msg instanceof TextMessage) {
> TextMessage txtMsg = (TextMessage) msg;
> System.out.println("Received message!" +
> txtMsg.getText());
> }
> if (msg == null) {
> break;
> }
> }
> }
> catch (Exception e) {
> System.out.println("Got exception when receiving.");
> }
> }
> public static void main(String... args) throws Exception {
> System.setProperty(MatsTestBroker.SYSPROP_MATS_TEST_BROKER,
> MatsTestBroker.SYSPROP_MATS_TEST_BROKER_VALUE_ARTEMIS);
> new Test_MatsTestBroker().test();
> System.out.println("Done!");
> }
> public static EmbeddedActiveMQ createArtemisBroker(String brokerUrl) {
> Configuration config = new ConfigurationImpl();
> try {
> config.setSecurityEnabled(false);
> config.setPersistenceEnabled(false);
> config.addAcceptorConfiguration("in-vm", brokerUrl);
> // :: Configuring for separate DLQs, with pattern (which is
> default) "DLQ." as prefix.
> config.addAddressesSetting("#",
> new AddressSettings()
>
> .setDeadLetterAddress(SimpleString.toSimpleString("DLQ"))
> .setMaxDeliveryAttempts(3)
> .setAutoCreateQueues(true) // default true
> .setAutoCreateAddresses(true) // default true
> .setAutoCreateDeadLetterResources(true) //
> CHANGED! default false
>
> .setDeadLetterQueuePrefix(SimpleString.toSimpleString("DLQ.")) // default
> "DLQ."
>
> .setDeadLetterQueueSuffix(SimpleString.toSimpleString("")) // default ""
>
> .setExpiryAddress(SimpleString.toSimpleString("ExpiryQueue")));
> // :: This is just trying to emulate the default config from
> default broker.xml - inspired by Spring
> // Boot which also got problems with default config in embedded
> mode being a tad lacking.
> //
> https://github.com/spring-projects/spring-boot/pull/12680/commits/a252bb52b5106f3fec0d3b2b157507023aa04b2b
> config.addAddressConfiguration(
> new CoreAddressConfiguration()
> .setName("DLQ")
> .addRoutingType(RoutingType.ANYCAST)
> .addQueueConfiguration(new
> QueueConfiguration("DLQ")
> .setRoutingType(RoutingType.ANYCAST)));
> config.addAddressConfiguration(
> new CoreAddressConfiguration()
> .setName("ExpiryQueue")
> .addRoutingType(RoutingType.ANYCAST)
> .addQueueConfiguration(new
> QueueConfiguration("ExpiryQueue")
> .setRoutingType(RoutingType.ANYCAST)));
> }
> catch (Exception e) {
> throw new AssertionError("Can't config the Artemis
> Configuration.", e);
> }
> EmbeddedActiveMQ server = new EmbeddedActiveMQ();
> server.setConfiguration(config);
> try {
> server.start();
> }
> catch (Exception e) {
> throw new AssertionError("Can't start the Artemis Broker.", e);
> }
> return server;
> }
> }
> {code}
>
>
--
This message was sent by Atlassian Jira
(v8.3.4#803005)