RabbitMQ Advanced | Dark Horse

1. Reliable message delivery

production side

When using RabbitMQ, as a message sender, you want to prevent any message loss or delivery failure scenarios.

RabbitMQ provides us with two ways to control the reliability mode of message delivery.

  • confirm confirmation mode
  • return return mode

The path of rabbitmq's entire message delivery is:

producer--->rabbitmq broker--->exchange--->queue--->consumer

  • Cancellation from producer to exchange will return a confirmCallback
  • If the message fails to be delivered from  exchange-->queue, a returnCallback will be returned

We will use these two callbacks to control the reliable delivery of messages

confirmCallback 

returnCallback 

二、Consumer Ack

consumer side

ack refers to acknowledge, confirmation. Indicates the confirmation method of the consumer after receiving the message

Three kinds:

  • Automatic confirmation: acknowledge="none
  • Manual confirmation: acknowledge="manual
  • Confirm according to the abnormal situation: acknowledge="auto" (this method is troublesome to use, no explanation will be given)

Automatic confirmation means that once a message is received by Consumer, it will automatically confirm receipt and remove the corresponding mesage from RabbitMQ's message cache. However, in actual business processing, it is very likely that the message is received and the business processing is abnormal, and the message will be lost.

If the manual confirmation method is set, you need to call channel.basicAck0 to sign for it manually after the business processing is successful. If there is an exception, call the channel.basicNack0 method to let it automatically resend the message.

1. Automatic confirmation

If nothing is configured, the default is automatic confirmation

2. Manual confirmation

What is implemented is not messagelistener but its sub-interface, and then enable manual confirmation

3. Summary

3. Current limiting 

This configuration means that manual reception is used, and then only one message is received at a time, and the next one comes after manual confirmation. If prefetch="1" is removed, all messages will be pulled over at one time.

Configure the prefetch attribute in <rabbit:listener-container> to set how many messages the consumer pulls at a time.
The confirmation mode of the consumer must be manual confirmation, acknowledge="manual"

4. TTL

Time to Live (survival time/expiration time)

When the message reaches the survival time and has not been consumed, it will be automatically cleared

RabbitMQ can set the expiration time for the message, or set the expiration time for the entire queue

1. The queue expires uniformly

Configure the queue and switch, and set the expiration time of the queue to 10 seconds

After the queue expires, all messages will be deleted uniformly

After the message expires, only when the message is at the top of the queue will it be judged whether it has expired and then deleted immediately. If it is not at the top of the queue, it will only be judged whether it is expired before the message is used, which is very similar to the lazy deletion of redis

2. The message expires separately

After writing, pass this anonymous inner class into covertandsend as a parameter: 

If the expiration time of the message is set, the message time of the queue is also set, and the shortest time is the main one 

3. Summary

  • Set the queue expiration time using parameters: -message-ttl, unit: ms (milliseconds), it will uniformly expire the entire queue message
  • To set the message expiration time use the parameter: expiration. Unit: ms (milliseconds). When the message is at the head of the queue (when consumed), it will be judged whether the message is expired or not.
  • If both are set, whichever takes the shortest time

5. Dead letter queue

Other MQ does not have an exchange, so it is called a dead letter queue, but rabbitMQ has an exchange, so it is also called a dead letter switch

Dead letter queue, DLX. Dead letter Exchange (dead letter exchange), when the message becomes Dead message, it can be resent to another exchange, this exchange is handed over to DLX

If a message expires and is not consumed normally, if it is bound to a dead letter queue, it will not be discarded but will be sent to the dead letter switch and resent to another queue, and consumers can also be bound.

What news will become dead letter (emphasis)

  • Queue message length reached limit
  • The consumer rejects the consumption message, basicNack/basicReject, and does not put the message back into the original target queue, requeue=false
  • There is a message expiration setting in the original queue, and the message arrival timeout time has not been consumed

Queue binding dead letter exchange:

Set parameters for the queue: x-dead-letter-exchange and x-dead-letter-routing-key

The first parameter is to set the name of the dead letter switch, and the second parameter is the routingkey bound to the dead letter queue

6. Delay Queue

Scenario: After the user places an order, if the payment is not made within 30 minutes, the order will be canceled and the inventory will be rolled back.

Implementation method: timed task (not elegant), delay queue

The function of delay queue is not provided in RabbitMQ

However, we can achieve the effect of delay queue through TTL+DLX (dead letter queue)

We can define a queue with an expiration time of 30 minutes, bind a dead-letter switch, and then no consumer will monitor the dead-letter queue, and will not listen to the normal queue, just wait for it to expire, and it will be sent to the private message switch when it expires, and the dead-letter switch will then sent to consumers.

Seven, priority queue

The priority queue is executed according to the priority, not in the order of first in first out

 

Eight, lazy queue

Lazy queue: messages are stored on disk , while normal queues store messages in memory

Scenario: Inert queues are necessary when consumers are down or under maintenance, resulting in accumulation due to inability to consume for a long time.

The performance of the lazy queue will be relatively low, and it will take up very little memory.

Nine, application problems

1. Message compensation mechanism

Requirement: 100% guarantee that the message is sent successfully

First, the producer first puts the data into the database and then sends a message to queue 1. If the consumer receives it successfully, it also puts it into the database, and the consumer sends a confirmation message to queue 2 after receiving it. The producer will also delay sending messages to queue 3. Messages from queue 3 and queue 2 will be monitored to the callback check service. If their messages are different, if the message from queue 3 is not found in queue 2, it means that the message has not been sent successfully. Call producer Resend. What if both sending the message and delaying the send fail? There is also a scheduled task to regularly check the callback database to see if there is any data that is useless and call hseng

2. Guarantee of idempotency

Idempotency refers to one or more requests for a certain resource, which have the same result for a resource itself.

That is, the impact of any number of executions on the resource itself is the same as that of one execution

In MQ: Consume multiple identical messages and get the same result as consuming one message

For example, I bought something and drew 500 yuan, but for some reason mq sent two messages, and I had to ensure that only 500 yuan was deducted from the account

When we send a message, the version is 1, and if we send a message repeatedly, it will still be 1 or 1, but as long as one of us succeeds, the version of our database will become 2, so that even if the second version 1 comes over, it will be the same The updated version 2 is different and failed. Idempotency is guaranteed.

Guess you like

Origin blog.csdn.net/weixin_54232666/article/details/130072826