Delay queueing based on RABBITMQ implementation

Source: Internet
Author: User
This is a creation in Article, where the information may have evolved or changed.

Although RABBITMQ does not have the ability to delay the queue, but a little change can be achieved

Basic elements for implementing a delay queue

    1. There is a countdown mechanism: Time to Live (TTL)
    2. An event that sends a message is triggered when the point of time is reached: Dead letter exchanges (DLX)

$~~~~~~$ based on the 1th, I am using the message has the expiration time of the feature, once the message expires will become dead letter , you can have a separate message expires, you can also set the entire queue message expiration time
And rabbitmq will be limited to a minimum value of two values

$~~~~~~$ based on the 2nd, is the use rabbitmq of outdated message processing mechanism:
. x-dead-letter-exchangesends an expired message to the specified exchange
. x-dead-letter-routing-keysending expired messages to a custom set route

In this example, I'm using an expired message + forwarding the specified exchange

The implementation in the Golang

First, consumers.comsumer.go

Package Mainimport ("Log" "Github.com/streadway/amqp") Func FailOnError (Err error, msg string) {if err! = Nil { Log. Fatalf ("%s:%s", MSG, err)}}func main () {//Establish link conn, err: = Amqp. Dial ("amqp://guest:guest@localhost:5672/") FailOnError (Err, "Failed to connect to RabbitMQ") defer Conn. Close () ch, err: = conn. Channel () FailOnError (err, "Failed to open a channel") defer ch. Close ()//declares a primary use of exchange err = ch. Exchangedeclare ("Logs",//Name "Fanout",//type true,//durable false,//Auto-de leted false,//internal false,//no-wait nil,//arguments) FailOnError (err, "Fai Led to declare an Exchange ")//Declare a regular queue, in fact this is not necessary to declare, because Exchange will default to bind a queue q, err: = Ch.  Queuedeclare ("Test_logs",//Name false,//durable false,//delete when unused true,// Exclusive false,//no-wait nil,//arguments) FailoNerror (Err, "Failed to declare a queue")/** * Note that this is the focus!!!!! * Declare a delay queue, ß our delay message is to be sent here */_, Errdelay: = Ch. Queuedeclare ("Test_delay",//Name false,//durable false,//delete when unused true,/ /exclusive false,//no-wait AMQP.    table{//Send message to logs when the message expires this Exchange "X-dead-letter-exchange": "Logs",},//Arguments ) FailOnError (Errdelay, "Failed to declare a delay_queue") Err = ch. Queuebind (Q.name,//queue Name, which refers to Test_logs "",//Routing key "logs",//Exchange F Alse, nil) failOnError (err, "Failed to bind a queue")///The listener here is Test_logs msgs, err: = Ch.   Consume (Q.name,//queue Name, which refers to Test_logs "",//consumer true,//Auto-ack false, Exclusive false,//no-local false,//no-wait nil,//args) FailOnError (err, "faile D To register a consumer ") fOrever: = Make (chan bool) go func () {for D: = range msgs {log. Printf ("[x]%s", D.body)}} () log. PRINTF ("[*] waiting for logs. To exit Press CTRL + C ") <-forever}

Then the producer Productor.go

Package Mainimport ("Log" "OS" "Strings" "GITHUB.COM/STREADWAY/AMQP") Func FailOnError (Err error, MSG string) {if err! = Nil {log. Fatalf ("%s:%s", MSG, err)}}func main () {conn, err: = Amqp. Dial ("amqp://guest:guest@localhost:5672/") FailOnError (Err, "Failed to connect to RabbitMQ") defer Conn. Close () ch, err: = conn. Channel () FailOnError (err, "Failed to open a channel") defer ch. Close () Body: = Bodyfrom (OS. Args)//Send the message to the delay queue err = ch. Publish ("",//Exchange here is empty do not select Exchange "Test_delay"///Routing key false ,//Mandatory false,//immediate AMQP.    publishing{ContentType: "Text/plain", Body: []byte (body), Expiration: "5000", Set expiration time of five seconds}) FailOnError (err, "Failed to publish a message") log. Printf ("[x] Sent%s", body)}func bodyfrom (args []string) string {var s string if (len (args)< 2) | | Os. ARGS[1] = = "" {s = "Hello"} else {s = strings. Join (args[1:], "")} return s}

Run it:

go run comsumer.gogo run productor.go

$~~~~~~$ specific to the code and comments on the line, here is the key point is to delay the message sent to the expiration queue, and then listen to the expiration queue forwarded to the Exchange under the queue
The normal situation is to always listen to a queue, and then send the expired message to the delay queue, when the message arrives, send the message to the queue listening

A self-written MQ tool
Blog Original

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.