Get Discarded Messages

tsb
tsb Member Posts: 3

Hello,
I have encountered a certain situation when using solace and would like to ask: lets say we have a specific scenario where we have two
applications communicating with each other using a message queue. The binders and mq properties are configured in an application yaml
file and one of the files has a misplaced indentation which results to starting application 1 with queues that do not resolve placeholders,
e.g. it creates the wrong queues. In my situation i did not notice that which led to sending the events not to application two but to an
unknown queue, so my events never really deliver to anywhere.
I am using MessageChannel from org.springframework.messaging to send the events, with an additional class that
defines the message binding called MessageBindings and a spring cloudconfiguration class that uses @EnableBinding({MessageBindings.class}).
Since sending the events through this message channel actually puts them through this wrongly configured queue, the result returned is true
and no exception is thrown but there is a problem that there is no consumer to receive these events. In this scenario application 2 also
does not report any exceptions since it isnt receiving the events. The only way i found out that there is an actual problem was through
seeing that there were no logs from application two in Kibana and checking the Solace UI to see that the messages have been discarded.
Is there any way to configure solace/spring cloud stream so that it shows that the events have not reached the client since with MessageChannel
there seems to be no indication that the events have been discarded or send to a preconfigured dead message queue?
Thank you, BR

Comments

  • uherbst
    uherbst Member, Employee Posts: 130 Solace Employee

    Hi @tsb,
    some ideas for your issue:

    1. Don't publish to a queue, publish to a topic. (that's a global Solace recommendation for most use cases). Do you have any specific requirements to publish to a queue ?
      To consume the messages with application 2, you need to create somehow (different ways possible) a consumer queue, that has a subscription to that topic (or a wildcard topic).
      This way, you can extend later easily to multiple completeley independ consumers.

    2. If you really want to publish to a queue, configure that queue with a Dead Message Queue (DMQ) and a TTL (Time-to-Live). With this, your messages will be moved to the Dead Message Queue after let's say 2 hours.
      If you just want to see that misconfiguration and you don't need to save the discarded messages, you can also skip the DMQ and just have a look at the discard statistics for that queue.

    Uli

  • marc
    marc Member, Administrator, Moderator, Employee Posts: 963 admin
    edited April 2021 #3

    Hi @tsb,

    Are you using the Solace Spring Cloud Stream Binder? I'm guessing yes b/c the mention of @EnableBinding. If so it will automatically publish to topics and consume from queues as suggested by @uherbst.

    A few things to note in addition to the items mentioned by @uherbst:
    1. In general, when creating event-driven microservices using a publish/subscribe pattern the different apps are decoupled and not aware of each other. App A might be sending a message but doesn't know (or really care in many cases) if App B, App C, or Apps D through Z are going to receive it. Hence why your situation didn't result in an error. Both of your apps think they're find. One is sending successfully and the other is connected and waiting for incoming messages
    2. Having said #1, when it comes down to your business logic if you are expecting certain things to happen for your app to be considered healthy and those aren't happening you can always code your app to send some sort of anomaly event or even a periodic status message to let your monitoring systems know something is not operating as expected.
    3. If you're having issues with spacing in the yaml config you can use a properties file instead (for Spring apps)

  • tsb
    tsb Member Posts: 3

    @uherbst said:
    Hi @tsb,
    some ideas for your issue:

    1. Don't publish to a queue, publish to a topic. (that's a global Solace recommendation for most use cases). Do you have any specific requirements to publish to a queue ?
      To consume the messages with application 2, you need to create somehow (different ways possible) a consumer queue, that has a subscription to that topic (or a wildcard topic).
      This way, you can extend later easily to multiple completeley independ consumers.

    2. If you really want to publish to a queue, configure that queue with a Dead Message Queue (DMQ) and a TTL (Time-to-Live). With this, your messages will be moved to the Dead Message Queue after let's say 2 hours.
      If you just want to see that misconfiguration and you don't need to save the discarded messages, you can also skip the DMQ and just have a look at the discard statistics for that queue.

    Uli

    Hello Uli,
    There is actually a topic configured but since it was in the configurations where the placeholders couldnt resolve, i dont think it will make a difference. If the configurations are correct, everything works the way it should but since this case is rather specific, the topics themselves arent correctly configured as well
    there is a dmq and ttl but the events are immediately discarded and there is no indication of what the problem is, even if i check the UI, since i see that they are indeed discarded but i do not know the reason since no exception or anything similar occurs. if i didnt see that the initial setup was wrong i wouldnt have know why the events were discarded, only that they were
    I guess the only way for it to inform me that the events werent consumed is to have some sort of integration test?
    Thank you for your fast reply, BR

  • tsb
    tsb Member Posts: 3

    @marc said:
    Hi @tsb,

    Are you using the Solace Spring Cloud Stream Binder? I'm guessing yes b/c the mention of @EnableBinding. If so it will automatically publish to topics and consume from queues as suggested by @uherbst.

    A few things to note in addition to the items mentioned by @uherbst:
    1. In general, when creating event-driven microservices using a publish/subscribe pattern the different apps are decoupled and not aware of each other. App A might be sending a message but doesn't know (or really care in many cases) if App B, App C, or Apps D through Z are going to receive it. Hence why your situation didn't result in an error. Both of your apps think they're find. One is sending successfully and the other is connected and waiting for incoming messages
    2. Having said #1, when it comes down to your business logic if you are expecting certain things to happen for your app to be considered healthy and those aren't happening you can always code your app to send some sort of anomaly event or even a periodic status message to let your monitoring systems know something is not operating as expected.
    3. If you're having issues with spacing in the yaml config you can use a properties file instead (for Spring apps)

    Hi,
    Yes i am using Solace Spring Cloud Stream Binder. As far as i understand the only way that i can be sure that the events are being correctly consumed is to have some sort of integration test or otherwise implement some monitoring system?
    Thank you for your reply, BR

  • uherbst
    uherbst Member, Employee Posts: 130 Solace Employee
    edited April 2021 #6

    @uherbst said:
    1. Don't publish to a queue, publish to a topic. (that's a global Solace recommendation for most use cases). Do you have any specific requirements to publish to a queue ?
    To consume the messages with application 2, you need to create somehow (different ways possible) a consumer queue, that has a subscription to that topic (or a wildcard topic).

    @tsb said
    There is actually a topic configured but since it was in the configurations where the placeholders couldnt resolve, i dont think it will make a difference. If the configurations are correct, everything works the way it should but since this case is rather specific, the topics themselves arent correctly configured as well

    Ok, I should be more verbose about my idea:
    1. Publish persistent (you want to use queues, so I assume, this is no issue)
    2. Client profile for the publisher should have set "Reject Messages to Sender on No Subscription Match Discard"

    With this setting, your publisher will receive a Negative Acknowledgement (=exception) from the broker, if your topic has no subscriber or no subscribing queue.
    Do you look for something like this ?

    (To be honest - this idea was described from @nram in an internal discussion)

  • marc
    marc Member, Administrator, Moderator, Employee Posts: 963 admin
    edited April 2021 #7

    Yes i am using Solace Spring Cloud Stream Binder. As far as i understand the only way that i can be sure that the events are being correctly consumed is to have some sort of integration test or otherwise implement some monitoring system?
    Thank you for your reply, BR

    Okay this info helps!

    So a few things to keep in mind with the Cloud Stream Binder:
    1. It only supports Persistent Messaging
    2. It will publish to topics and consume from queues. If you define a "group" in your config Cloud Stream knows you want to use the "Consumer Group" pattern and it will create a Durable Non-Exclusive queue; if you don't define a "group" it will create a Non-Durable Exclusive Queue. Either of these queues would subscribe to topics configured in the app config.
    3. As @uherbst mentioned, if you want your publisher to know if there is no consumer/endpoint subscribed to the messages that are being sent you should be able to use the "Reject Messages to Sender on No Subscription Match Discard" on the client-profile. On the Cloud Stream side you'll want to check out the brand new Publisher Confirmations feature of the Solace binder and make sure you have the latest version since it was introduced in solace-spring-cloud v2.1.0.