1
votes
  • Spring JMSListener listens at /queue/app/*
  • The message is actually produced at /queue/app/XXX and so also available at the wildcard-address ( /queue/app/* ) to consume
  • Once the processing is successful at the listener, the message is acknowledged at the wildcard-address ( /queue/app/* ), but not the original address ( /queue/app/XXX ).

My concern is that the message will retain the storage till expiry.

How can we solve this?

Usecase

My setup is as follows -

Service A

Subscribes to /queue/A/*

Publishes to /queue/B/tenantId

Service B with TenantID = 1

Subscribes to /queue/B/1

Publishes to /queue/A/1

Service B with TenantID = 2

Subscribes to /queue/B/2

Publishes to /queue/A/2

Basically, Service A sends message to Service B via the independent-queues ( /queue/B/tenantId ) for different tenants. The idea behind separate queues for each tenant is to eliminate inter-tenant competition within the queue. Also, there will be multiple instances of Service B running for each tenant. Now once the Service B is done with the message-processing, it will publish the response-message back to Service A on the tenant-specific queue ( /queue/A/tenantId ). The idea here is to have the logical-isolation among tenant response-messages. Finally, the reason to use wildcard-address in Service A is because we can not have a dedicated consumer for each tenant in Service A and we plan to share it across tenants.

broker-00.xml

 <address-settings>
        <address-setting match="/queue/#">
            <default-address-routing-type>ANYCAST</default-address-routing-type>
            <default-queue-routing-type>ANYCAST</default-queue-routing-type>
        </address-setting>
        <address-setting match="/topic/#">
            <default-address-routing-type>MULTICAST</default-address-routing-type>
            <default-queue-routing-type>MULTICAST</default-queue-routing-type>
        </address-setting>


        <address-setting match="#">
            <auto-delete-queues>false</auto-delete-queues>
            <auto-delete-jms-queues>false</auto-delete-jms-queues>
            <auto-delete-jms-topics>false</auto-delete-jms-topics>
            <auto-delete-addresses>false</auto-delete-addresses>
            
            <max-delivery-attempts>15</max-delivery-attempts>


            <expiry-delay>86400000</expiry-delay>
            <redelivery-delay>3000</redelivery-delay>
            <redelivery-delay-multiplier>1</redelivery-delay-multiplier>
            <redelivery-collision-avoidance-factor>0.15</redelivery-collision-avoidance-factor>
            <max-redelivery-delay>50000</max-redelivery-delay>
            <default-consumer-window-size>0</default-consumer-window-size>
        </address-setting>
    </address-settings>
    <wildcard-addresses>
        <routing-enabled>true</routing-enabled>
        <delimiter>/</delimiter>
        <any-words>#</any-words>
        <single-word>*</single-word>
    </wildcard-addresses>
1
What protocol(s) are you using?Justin Bertram
Are you using anycastPrefix=/queue/ on your acceptor?Justin Bertram
I am using STOMP protocol from Service B and CORE protocol from Service A. I am not using anycastPrefix, instead I am using address-setting for /queue/# to create ANYCAST queues.Arshal Jain
Why did you select anycast? Does multicast not fit with your use-case? Also, please add relevant config to your question (e.g. address-settings you'd added, etc.).Justin Bertram
@JustinBertram I have added the details as requested. used anycast as I wanted a point-point communication. Also, I wanted only one pod of the Service-A to consume the message from the queue. In the case of multicast, my understanding is that if I have replicas of Service-A, all of them will receive the same message and I want to avoid that. Basically I want guaranteed and at most once delivery of messageArshal Jain

1 Answers

2
votes

You're seeing the expected behavior. Remember, it's a wildcard address, not a wildcard consumer. Messages sent to any address matching the wildcard address will be routed to the queues bound to the wildcard address and those messages are acknowledged independently of the messages routed to the particular address' queues where they were originally sent.

If you don't want messages to accumulate in any of queues then simply remove the queues and just have the address. An address without any queues is a perfectly valid configuration.