RabbitMQ(2): 队列使用

引言

在上一节【RabbitMQ(一)】docker-compose安装rabbitmq及简单使用Hello World中,我们介绍了Rabbitmq的安装和简单操作。达到了生产者发送一个Hello World之后,消费者便能接收到一个Hello World的效果。

  1. 如果有多个消费者同时在接收消息,消息会如何分发呢?
  2. 消费者在处理消息的时候宕机了,那这个消息怎么办呢?
  3. rabbitmq宕机了,其中的队列和消息怎么办?
  4. 两个消费者情况下,消息分发不合理,一个特忙,一个特闲怎么办?

带着这些问题,开始RabbitMQ第二节的学习内容,队列的使用及策略

循环调度

使用任务队列的优点之一是能够轻松并行化工作。如果我们的工作正在积压,我们可以增加更多的工人,这样就可以轻松扩展。

这里我们利用上一节中consumer.go开启两个consumer在准备接收消息,然后不断运行producer.go,会发现结果是怎样的呢?

代码部分就不做展示运行了,不难发现两个consumer是一次循环接收到了消息,也就是第一个消息被consumer1接收,第二个消息便会被consumer2接收,依次循环下去。也可以开启3个consumer甚至更多看一样,结果都是一样的。

这样我们可以得出结果:

默认情况下,RabbitMQ将按顺序将每个消息发送给下一个消费者。平均而言,每个消费者都会收到相同数量的消息。这种分发消息的方式称为轮询

消息确认

consumer 完成任务可能需要耗费几秒钟,如果一个consumer在任务执行过程中宕机了该怎么办呢?我们当前的代码中,RabbitMQ一旦向消费者传递了一条消息,便立即将其标记为删除。在这种情况下,如果你终止一个consumer那么你就可能会丢失这个任务,我们还将丢失所有已经交付给这个consumer的尚未处理的消息。

我们不想丢失任何消息,如果一个consumer意外宕机了,那么我们希望将任务交付给其他consumer来处理。

为了确保消息永不丢失,RabbitMQ支持 消息确认消费者发送回一个确认(acknowledgement),以告知RabbitMQ已经接收,处理了特定的消息,并且RabbitMQ可以自由删除它。

如果使用者在不发送确认的情况下死亡(其通道已关闭,连接已关闭或TCP连接丢失),RabbitMQ将得知消息未完全处理,并将对其重新排队。如果同时有其他消费者在线,它将很快将其重新分发给另一个消费者。这样,您可以确保即使工人偶尔死亡也不会丢失任何消息。

没有任何消息超时;RabbitMQ将在消费者死亡时重新传递消息。即使处理一条消息需要很长时间也没关系。

手动确认模式

在这里,我们将使用手动消息确认,方法是为“auto-ack”参数传递一个false,然后在完成任务后,使用d.Ack(false)从consumer发送一个正确的确认(这将确认一次传递)。

将第一节中的consumer.go在接收消息时由自动消息确认模式切换成手动传递消息确认,完整代码如下:

package main

import (
	"log"
	"time"

	"github.com/streadway/amqp"
)

func main() {
   
	// 建立连接
	conn, err := amqp.Dial("amqp://root:[email protected]:5672/")
	if err != nil {
   
		log.Fatalf("%s", "Failed to connect to RabbitMQ", err)
		return
	}
	defer conn.Close()

	// 获取channel
	ch, err := conn.Channel()
	if err != nil {
   
		log.Fatalf("%s", "Failed to open a channel", err)
		return
	}
	defer ch.Close()

	// 声明队列
	//请注意,我们也在这里声明队列。因为我们可能在发布者之前启动使用者,所以我们希望在尝试使用队列中的消息之前确保队列存在。
	q, err := ch.QueueDeclare(
		"hello", // name
		false,   // durable
		false,   // delete when unused
		false,   // exclusive
		false,   // no-wait
		nil,     // arguments
	)
	if err != nil {
   
		log.Fatalf("%s", "Failed to declare a queue", err)
		return
	}
	// 获取接收消息的Delivery通道
	msgs, err := ch.Consume(
		q.Name, // queue
		"",     // consumer
		false,  
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值