Artemis receives duplicate messages after failover [duplicate] - duplicates

This question already has an answer here:
ActiveMQ messageId not working to stop duplication
(1 answer)
Closed 2 years ago.
In order to test the communication performance in the event of a failure, I numbered each message and sent it continuously, sending about 30 messages per second. And found that even if the ha policy is set, consumers will repeatedly receive a small number of received messages after failover/failback. Is this normal?
I know that Artemis provides automatic duplicate message detection by giving a unique value to the message, which can avoid repeated sending of messages, but the repeated received messages have different "client ack messageID". Does this mean that it cannot prevent receiving repeated messages?

Depending on how you've written your client you can get duplicates on failover because some message acknowledgements may get lost when the failure happens. For example, if you receive a message from the broker and process it but then the broker fails before you send the acknowledgement (or fails while the acknowledgement is in transit) then the backup will still have the message you received already and will dispatch it again.
If you don't want duplicates to be a problem for your client then you have a couple of options:
Use a transaction on your client and don't commit until the acknowledgement has been confirmed successfully. If the acknowledgement fails then rollback the transaction.
Make sure your consumer is idempotent so duplicates don't really matter.

Related

How does Amazon SQS takes care of not sending same message to different instances of same service?

I have a queue ( in this case Amazon SQS ) and there are N nodes of same service running which are consuming messages from SQS.
How can I make sure that during any point of time, not more than one nodes has read a same message from queue.
In case of Kafka, we know that, not more than one consumer from the same consumer group can be assigned to a single topic partition. How do we make sure the same thing is handled inside Amazon SQS or not ?
The Amazon mechanism to prevent that a message is delivered to multiple consumers is the Visibility Timeout:
Immediately after a message is received, it remains in the queue. To prevent other consumers from processing the message again, Amazon SQS sets a visibility timeout, a period of time during which Amazon SQS prevents other consumers from receiving and processing the message. The default visibility timeout for a message is 30 seconds. The minimum is 0 seconds. The maximum is 12 hours.
After the message is received, SQS starts the timeout and for its duration, it doesn't send it again to other consumers. After the timeout ends, if the message has not been deleted, SQS makes it available again for other consumers.
But as the note says:
For standard queues, the visibility timeout isn't a guarantee against receiving a message twice. For more information, see At-Least-Once Delivery.
If you need absolute guarantees of only once delivery, you have to option:
Design your application to be idempotent so that the result is
the same if it process the same message one or more time.
Try
using a SQS FIFO queue that provides exactly once processing.

postfix: timing of client responses in a milter and in after-queue processing?

I'm currently using postfix-2.11.3, and I am doing a lot of message processing through a milter. This processing takes place before the client is notified that the message is accepted, and it sometimes involves enough work that it delays the client's receipt of the initial SMTP 250 2.0.0 Ok: queued as xxxxxxxxxxx message.
During large email blasts to my server, this milter processing can cause a backlog, and in some cases, the client connections time out while waiting for that initial 250 ... message.
My question is this: if I rewrite my milter as a postfix after-queue filter with no before-queue processing, will clients indeed get the initial 250 messages right away, with perhaps subsequent SMTP messages coming later? Or will the 250 message still be deferred until after postfix completes the after-queue filtering?
And is it possible for an initial 250 message to be received by the client with a subsequent 4xx or 5xx message received and processed later by that same client, in case the after-queue filter decides to subsequently reject the message?
I know I could test this by writing an after-queue filter. However, my email server is busy, and I don't have a test server available, and so I'd like to know in advance whether an after-queue filter can behave in this manner.
Thank you for any wisdom you could share about this.
I managed to set up a postfix instance on a test machine, and I was able to install a dummy after-queue filter. This allowed me to figure out the answer to my question. It turns out that postfix indeed sends the 250 2.0.0 Ok: queued as xxxxxxxxxxx message before the after-queue filter completes.
This means that I can indeed move my slower milter processing to the after-queue filter in order give senders a quicker SMTP response.

How to deal with multiple request to server from client

I've my messenger app which sends request to server for group creation, server process the request(making a database entry of group) and send back response, but sometimes it happens due to weak connection, response is not received in particular time instant, as a result client sends request again for the same group.
The fault which occurs in this case the server processes both these request and makes two entries (or more in case of more requests) in the database with different group_id for the same group.
How can I avoid multiple entries in database and make it consistent?
Due to multiple entries, when client reinstall app, if there are three entries of a group in database, all three will be loaded in app.
One solution which I thought of is that check if the group with given name already exist, but this is not the accepted solution, since client can create more one group with same name.
Note:
I'm using MYSQL Enterprise edition for storing entries on server.
You can think of group creation as same as groups are created in WhatsApp messenger.
Packet Id is unique for such repeating JSON requests being sent to server. Use that as a filter and discard the duplicate packet Ids. Same as done with message packets and other requests.

Amazon SQS Worker Tier Auto Scaling fails

We have an SQS Worker Tier app subscribed to a queue. When it is running it works fine, however, when it gets busy, and scales up, the new instance starts getting messages almost immediately, before it is actually ready. This results in 500 responses, and the messages being discarded to the dead letter queue.
We have our queue configured with a maximum attempt of 1; due to the database changes a message will make during consumption we can't just put it back in the queue in case of error.
I have tried using the monitor health url as I would with a normal web app, but this doesn't seem to work as messages continue to be sent regardless.
Is there any way of setting a delay on any new auto scaled instance before is starts receiving messages from the queue?
I am not sure how the instance is 'getting messages' before its ready, unless you are actually using SNS to PUSH the messages to the endpoint, as opposed to having the endpoint(instance) PULL the messages from the queue.
If you are pushing messages via SNS, then the easiest solution is to have the instance POLL the SQS queue for messages when its ready to process them - much safer and reliable, and obviously the instance can decide for itself when its ready to do work.
It also sounds to me like you solution is not architected properly. If accidentally processing the same message twice would cause you problems in your database, then your not using SQS in the correct manner. Work that SQS does should be idempotent - i.e. it should be able to processed more than one time without causing problems. Even when everything is running 100% correctly, on your end and at AWS, its possible that the same message will be sent more than once to your workers - you can't prevent that - and your processing needs to be able to handle that gracefully.
You can set the HTTP Connection setting (Configuration > Worker Configuration) in order to limit the number of concurrent connections to your worker. If you set it to 1, you're sure that 1 worker won't receive another request unless it has already responded.

Does a timed out HTTP POST result in SQL rollback?

From a question I asked previously (Preventing duplicate INSERTS MySQL) another question arose:
If a client delivers a POST request to a server, the server handles the POST, inserts into SQL and what not, then sends a reply (or at least HTTP 200 OK), but that reply is not received by the client... does the SQL statement then "not count" or does it auto-rollback or something?
This is very fundamental to using INSERT in POSTS for rows that cannot be uniquely identified by the client making the POST.
Generally speaking, no, the server will not roll back the sql insert. The request was handled on the server side, and then completed.
Think of the server handling it like entering a function. Once the functions job is complete, it returns whatever need be (in this case, the response to the client), and then is done with. The same process happens here, the server does not wait to see whether or not the client has received the request as it's function has already been completed.