1

I have a strange/critical problem on our production system with ActiveMQ Artemis. It occurs approximately every 1-2 months, and when it occurs it will (re)generate queue items exponentially.

We use ActiveMQ Artemis 2.18.0 with .NET Core 3.1 with Apache.NMS.ActiveMQ.NetStd 1.8.0 and Apache.NMS.AMQP 1.8.1.

When we receive a notification from the queue and if the request is temporarily not-processable, we re-queue the item with _AMQ_SCHED_DELIVERY so that the re-delivery will be performed later. We set the _AMQ_SCHED_DELIVERY manually rather than letting the broker deal with redelivery automatically with a redelivery delay because we want to redeliver message only on specific occasions (e.g. when payment provider answers that we should wait and retry later).

In these situations we somehow receive two or three notification in parallel (we have log a entry when we receive a queue notification). At the end the queue will be filled with the (re)queued items, and we would need to shutdown ActiveMQ Artemis and empty the queue items manually.

Does anyone have same (or similar) symptoms (and hopefully solved already)?

Message is sent with 'transaction' and as soon as message is received, we call message.acknowledge() and then session.commit(). The queue is created on-the-fly (i.e. not configured in broker.xml).

Here is broker.xml:

<configuration xmlns="urn:activemq" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xi="http://www.w3.org/2001/XInclude" xsi:schemaLocation="urn:activemq /schema/artemis-configuration.xsd">
  <core xmlns="urn:activemq:core" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="urn:activemq:core ">
    <name>ac3bc22d67ca</name>
    <persistence-enabled>true</persistence-enabled>
    <journal-type>ASYNCIO</journal-type>
    <paging-directory>data/paging</paging-directory>
    <bindings-directory>data/bindings</bindings-directory>
    <journal-directory>data/journal</journal-directory>
    <large-messages-directory>data/large-messages</large-messages-directory>
    <journal-datasync>true</journal-datasync>
    <journal-min-files>2</journal-min-files>
    <journal-pool-files>10</journal-pool-files>
    <journal-device-block-size>4096</journal-device-block-size>
    <journal-file-size>10M</journal-file-size>
    <journal-buffer-timeout>28000</journal-buffer-timeout>
    <journal-max-io>4096</journal-max-io>
    <disk-scan-period>5000</disk-scan-period>
    <max-disk-usage>99</max-disk-usage>
    <critical-analyzer>true</critical-analyzer>
    <critical-analyzer-timeout>120000</critical-analyzer-timeout>
    <critical-analyzer-check-period>60000</critical-analyzer-check-period>
    <critical-analyzer-policy>HALT</critical-analyzer-policy>
    <page-sync-timeout>152000</page-sync-timeout>
    <global-max-messages>-1</global-max-messages>
    <acceptors>
      <acceptor name="artemis">tcp://0.0.0.0:61616?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;amqpMinLargeMessageSize=102400;protocols=CORE,AMQP,STOMP,HORNETQ,MQTT,OPENWIRE;useEpoll=true;amqpCredits=1000;amqpLowCredits=300;amqpDuplicateDetection=true;supportAdvisory=false;suppressInternalManagementObjects=false</acceptor>
      <acceptor name="amqp">tcp://0.0.0.0:5672?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=AMQP;useEpoll=true;amqpCredits=1000;amqpLowCredits=300;amqpMinLargeMessageSize=102400;amqpDuplicateDetection=true</acceptor>
      <acceptor name="stomp">tcp://0.0.0.0:61613?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=STOMP;useEpoll=true</acceptor>
      <acceptor name="hornetq">tcp://0.0.0.0:5445?anycastPrefix=jms.queue.;multicastPrefix=jms.topic.;protocols=HORNETQ,STOMP;useEpoll=true</acceptor>
      <acceptor name="mqtt">tcp://0.0.0.0:1883?tcpSendBufferSize=1048576;tcpReceiveBufferSize=1048576;protocols=MQTT;useEpoll=true</acceptor>
    </acceptors>
    <security-settings>
      <security-setting match="#">
        <permission type="createNonDurableQueue" roles="amq"/>
        <permission type="deleteNonDurableQueue" roles="amq"/>
        <permission type="createDurableQueue" roles="amq"/>
        <permission type="deleteDurableQueue" roles="amq"/>
        <permission type="createAddress" roles="amq"/>
        <permission type="deleteAddress" roles="amq"/>
        <permission type="consume" roles="amq"/>
        <permission type="browse" roles="amq"/>
        <permission type="send" roles="amq"/>
        <permission type="manage" roles="amq"/>
      </security-setting>
    </security-settings>
    <address-settings>
      <address-setting match="activemq.management#">
        <dead-letter-address>DLQ</dead-letter-address>
        <expiry-address>ExpiryQueue</expiry-address>
        <redelivery-delay>0</redelivery-delay>
        <max-size-bytes>-1</max-size-bytes>
        <message-counter-history-day-limit>10</message-counter-history-day-limit>
        <address-full-policy>PAGE</address-full-policy>
        <auto-create-queues>true</auto-create-queues>
        <auto-create-addresses>true</auto-create-addresses>
      </address-setting>
      <address-setting match="#">
        <dead-letter-address>DLQ</dead-letter-address>
        <expiry-address>ExpiryQueue</expiry-address>
        <redelivery-delay>0</redelivery-delay>
        <max-size-bytes>-1</max-size-bytes>
        <max-size-messages>-1</max-size-messages>
        <message-counter-history-day-limit>10</message-counter-history-day-limit>
        <address-full-policy>PAGE</address-full-policy>
        <auto-create-queues>true</auto-create-queues>
        <auto-create-addresses>true</auto-create-addresses>
        <auto-delete-queues>false</auto-delete-queues>
        <auto-delete-addresses>false</auto-delete-addresses>
      </address-setting>
    </address-settings>
    <addresses>
      <address name="DLQ">
        <anycast>
          <queue name="DLQ"/>
        </anycast>
      </address>
      <address name="ExpiryQueue">
        <anycast>
          <queue name="ExpiryQueue"/>
        </anycast>
      </address>
    </addresses>
  </core>
</configuration>

Consumer Code (Simplified)

consumer.Listener += this.OnReceive;

private void OnReceive(IMessage message)
{
    var textMessage = message as ITextMessage;
    message.Acknowledge();
    this.Session.Commit();
    // here comes the real logic for handling the request.
Tettsuan
  • 11
  • 2
  • Does this happen with both clients? Does this happen with the latest release of ActiveMQ Artemis (i.e. 2.24.0)? How come you're manually sending the message with `_AMQ_SCHED_DELIVERY` rather than just allowing the broker to deal with it using a redelivery delay? – Justin Bertram Sep 01 '22 at 00:29
  • We use 'ISession.CreateConsumer' to create consumer(client) and use endpoint url as `tcp://artemis:61616` and the destination port is amqp. Sorry, I'm not 100% sure what you refer with 'both' clients. For the redelivery we set the `_AMQ_SCHED_DELIVERY` because we want to redeliver message only on specific occasion (when payment provider answers that we should wait and retry later). – Tettsuan Sep 02 '22 at 02:00
  • You say you're using .NET Core 3.1 with Apache.NMS.ActiveMQ.NetStd 1.8.0 and Apache.NMS.AMQP 1.8.1. Those are 2 different clients. They use OpenWire and AMQP respectively. Do you see the same behavior when using either of these clients? The `acceptor` configured in `broker.xml` listening on port `61616` supports both OpenWire and AMQP. – Justin Bertram Sep 02 '22 at 02:24
  • Also, you didn't indicate if you see this same behavior with the latest release of ActiveMQ Artemis (i.e. 2.24.0). – Justin Bertram Sep 02 '22 at 02:25
  • thanks for the clarification! I've traced the code and the Instances (connection/session/consumer) are all from Apache.NMS.ActiveMQ.DLL (1.8.0). also I've checked the protocol in management console and it was 'OPENWIRE'. we have recently upgraded to 2.23.1 and 2.24 is still in test. the problem hasn't occurred with 2.23.1. but I cannot tell if the problem no longer occurs with the new version, since it's just a week or so. – Tettsuan Sep 02 '22 at 04:21
  • If you're only actually using the OpenWire client then how is the AMQP client related to this? You mention it in your question, but it I don't understand where it fits into this problem. – Justin Bertram Sep 02 '22 at 13:16
  • Also, are you receiving the message with a transaction? Can you paste your consumer code? – Justin Bertram Sep 02 '22 at 13:17
  • Regarding AMQP, you are absolutely right. it was only referenced in the projects, I have removed the package references and executed the tests. it was successful. – Tettsuan Sep 04 '22 at 03:09

0 Answers0