Rabbitmq: Difference between revisions

From 탱이의 잡동사니
Jump to navigation Jump to search
Line 56: Line 56:
)
)
failOnError(err, "Failed to declare a queue")
failOnError(err, "Failed to declare a queue")
</source>
Although this command is correct by itself, it would be possible to doesn't work. Because if it already defined queue, which is not durable, the RabbitMQ doesn't allow you to redefine an existing queue with different parameters and will return an error to any program that tries to do that.
Now we need to makr our messages as persistent - by supplying a 'DeliveryMode: amqp.Persistent'.
<source lang=go>
err = ch.Publish(
"",    // exchange
q.Name, // routing key
false,  // mandatory
false,
amqp.Publishing{
DeliveryMode: amqp.Persistent,
ContentType:  "text/plain",
Body:        []byte(body),
},
)
</source>
</source>



Revision as of 19:09, 8 December 2018

Overview

Rabbit MQ 내용 정리

Basic

RabbitMQ is a message broker: it accepts and forwards messages. You can think about it as a post office: when you put the mail that you want posting in a post box, you can be sure that Mr. or Ms. Mailperson will eventually deliver the mail to your recipient. In this analogy, RabbitMQ is a post box, a post office and a postman.

Producing

Producing means nothing more than sending. A program that sends message is a producer.

Queue

A queue is the name for a post box which lives inside RabbitMQ. Although messages flow through RabbitMQ and your applications, they can only be stored inside a queue. A queue is only bound by the host's memory & disk limits, it's essentially a large message buffer. Many producers can send messages that go to one queue, and many consumers can try to receive data from one queue.

Consuming

Consuming has a similar meaning to receiving. A consumer is a program that mostly waits to receive messages.

Queue

Round-robin dispatching

By default, RabbitMQ will send each message to the next consumer, in sequence. On average every consumer will get the same number of messages. This ways of distributing message is called round-robin.

Message acknowledgement

Doing a task can take a few seconds. You may wonder what happen if one of the consumer starts a long task and dies with it only partly done. With simple configuration, once RabbitMQ delivers message to the customer it immediately marks it for deletion. In this case, if you kill worker we will lose the message it was just processing. We'll also lose all the messages that were dispatched to this particular worker but were not yet handled.

In order to make sure a message is never lost, RabbitMQ supports message acknowledgements. An ack(nowledgement) is sent back by the consumer to tell RabbitMQ that a particular message had been received, processed and that Rabbit MQ is free to delete it.

If a consumer dies (its channel is close, connection is closed, or TCP connection is lost) without sending an ack, RabbitMQ will understand that a message wasn't processed fully and will re-queue it. If there are other consumers online at the same time, it will then quickly redeliver it to another consumer. That way you can be sure that no message is lost, even if the workers occasionally die.

There aren't any message timeouts: RabbitMQ will redeliver the message when the consumer dies. It's fine even if processing a message takes a very, very long time.

Manual message acknowledgments are turned on by default.

Acknowledgement must be sent on the same channel the delivery it is for was received on. Attempts to acknowledge using a different channel will result in a channel-level protocol exception.

Forgotten acknowledgement

It's a common mistake to miss the 'basic_ack'. It's an easy error, but the consequences are serious. Messages will be redelivered when your client quits (which may look like random redelivery), but RabbitMQ will eat more and more memory as it won't able to release any unacked messages.

In order to debug this kind of mistake you can use 'rabbitmqctl' to print the 'messages_unacknowledged' field.

$ sudo rabbitmqctl list_queues name messages_ready messages_unacknowledged
Listing queues ...
hello	0	0
task_queue	0	0

Message durability

When RabbitMQ quits or crashes it will forget the queues and messages unless you tell it not to. Two things are required to make sure that messages aren't lost: we need to mark both the queue and messages as durable.

First, we need to make sure that RabbitMQ will never lose our queue. In order to do so, we need to declare it as durable: <source lang=go> q, err := ch.QueueDeclare( "task_queue", // name true, // durable false, // delete when unused false, // exclusive false, // no-wait nil, // arguments ) failOnError(err, "Failed to declare a queue") </source>

Although this command is correct by itself, it would be possible to doesn't work. Because if it already defined queue, which is not durable, the RabbitMQ doesn't allow you to redefine an existing queue with different parameters and will return an error to any program that tries to do that.

Now we need to makr our messages as persistent - by supplying a 'DeliveryMode: amqp.Persistent'. <source lang=go> err = ch.Publish( "", // exchange q.Name, // routing key false, // mandatory false, amqp.Publishing{ DeliveryMode: amqp.Persistent, ContentType: "text/plain", Body: []byte(body), }, ) </source>

See also