我正在尝试在Go中编写RabbitMQ Consumer。假设从队列中一次取出5个对象并处理它们。此外,假设确认是否成功处理了否则发送到死信队列5次然后丢弃,它应该无限运行并处理消费者的取消事件。 我几乎没有问题:
BasicConsumer
vs EventingBasicConsumer
的概念?Model
是什么,它是否在RabbitMq-go中?ttl
consumerTag
函数中ch.Consume
参数的重要性channel.Get()
还是channel.Consume()
?我需要在下面的代码中进行哪些更改才能满足上述要求。我问这个是因为我找不到像RabbitMq-Go那样的文档。
func main() {
consumer()
}
func consumer() {
objConsumerConn := &rabbitMQConn{queueName: "EventCaptureData", conn: nil}
initializeConn(&objConsumerConn.conn)
ch, err := objConsumerConn.conn.Channel()
failOnError(err, "Failed to open a channel")
defer ch.Close()
msgs, err := ch.Consume(
objConsumerConn.queueName, // queue
"demo1", // consumerTag
false, // auto-ack
false, // exclusive
false, // no-local
false, // no-wait
nil, // args
)
failOnError(err, "Failed to register a consumer")
forever := make(chan bool)
go func() {
for d := range msgs {
k := new(EventCaptureData)
b := bytes.Buffer{}
b.Write(d.Body)
dec := gob.NewDecoder(&b)
err := dec.Decode(&k)
d.Ack(true)
if err != nil { fmt.Println("failed to fetch the data from consumer", err); }
fmt.Println(k)
}
}()
log.Printf(" Waiting for Messages to process. To exit press CTRL+C ")
<-forever
}
编辑问题:
我已根据链接link1 link2中的建议延迟了对邮件的处理。但问题是即使在ttl之后,消息也从死信队列回到原始队列。我正在使用RabbitMQ 3.0.0
。谁能指出问题是什么?
答案 0 :(得分:2)
是否存在BasicConsumer与EventingBasicConsumer的概念 RabbitMq-go参考?
不完全相同,但Channel.Get
和Channel.Consume
调用提供了类似的概念。使用Channel.Get
,您有一个非阻塞调用,如果有可用的话,会收到第一条消息,或者返回ok=false
。使用Channel.Consume
,排队的消息将传递到频道。
RabbitMQ中的模型是什么,它是否在RabbitMq-go中?
如果你在C#RabbitMQ中引用IModel
和Connection.CreateModel
,那就是来自C#lib,而不是来自RabbitMQ本身。这只是试图从RabbitMQ“频道”术语中抽象出来,但它从未流行起来。
如果在死信队列失败时再次发送对象 在ttl
之后重新排队
将delivery.Nack方法与requeue=false
一起使用。
ch.Consume中consumerTag参数的意义是什么 函数在下面的代码中
ConsumerTag
只是一个消费者标识符。它可用于取消channel.Cancel的渠道,并识别负责交付的消费者。随channel.Consume
一起发送的所有邮件都会设置ConsumerTag
字段。
我们应该在这种情况下使用
channel.Get()
或channel.Consume()
吗?
我认为channel.Get()
几乎不会优于channel.Consume()
。使用channel.Get
,您将轮询队列并浪费CPU无所事事,这在Go中没有意义。
我需要在下面的代码中进行哪些更改才能满足上述要求 要求。
由于您一次批量处理5个,因此您可以使用从消费者渠道接收的goroutine,一旦获得5个交付,您可以调用另一个函数来处理它们。
要确认或发送到死信队列,您将使用delivery.Ack或delivery.Nack功能。您可以使用multiple=true
并为批次调用一次。一旦消息进入死信队列,您必须检查delivery.Headers["x-death"]
标题是否已被删除多少次,并在已经重试5次时调用delivery.Reject。
使用channel.NotifyCancel处理取消事件。