我在Go中有一个RabbitMQ使用者脚本(这是RabbitMQ tutorial使用streadway/amqp库的简单脚本)
问题在于,如果rabbitmq-server停止,则消费者脚本不会退出,当再次启动rabbitmq-server时,消费者不再接收消息。
有没有办法检测消费者连接是否已死并重新连接或至少终止消费者脚本?
我知道它设定默认值为10秒。连接的心跳间隔,是否可以使用它?
感谢您的帮助
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()
q, err := ch.QueueDeclare(
"test_task_queue", // name
true, // durable
false, // delete when unused
false, // exclusive
false, // no-wait
nil, // arguments
)
failOnError(err, "Failed to declare a queue")
err = ch.Qos(
1, // prefetch count
0, // prefetch size
false, // global
)
failOnError(err, "Failed to set QoS")
msgs, err := ch.Consume(
q.Name, // queue
"", // consumer
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 {
log.Printf("Received a message: %s", d.Body)
d.Ack(false)
dot_count := bytes.Count(d.Body, []byte("."))
t := time.Duration(dot_count)
time.Sleep(t * time.Second)
log.Printf("Done")
}
}()
log.Printf(" [*] Waiting for messages. To exit press CTRL+C")
<-forever
}
答案 0 :(得分:11)
amqp.Connection
有方法NotifyClose()
,它返回信号传输传输或协议错误。
像
for { //reconnection loop
conn, err := amqp.Dial("amqp://guest:guest@localhost:5672/") //setup
notify := conn.NotifyClose(make(chan *amqp.Error)) //error channel
...
ch, err := conn.Channel()
msgs, err := ch.Consume(
...
for{ //receive loop
select { //check connection
case err = <-notify:
//work with error
break //reconnect
case d = <- msgs:
//work with message
...
}
}
}
答案 1 :(得分:0)
尚未发现go-amqp库实现了连接池的断开连接和重新连接功能。
github上有一个基于Amqp二级打包的开源代码。
支持断开连接和异常重新连接后重新连接。该代码也相对易于使用,并且每个服务都有一个连接和通道。
Git地址:https://github.com/billmi/go-rabbit
示例代码:
package main
import (
"go-rabbit/rabbit"
)
/*
support isconnection and reconnection function
And Failure re-send function
@author : Bill
*/
func main() {
var(
addr = "amqp://guest:guest@localhost:5672/"
queue = "testQueue"
exchange = "test_exchange"
routerKey = "/test"
msg = "test1!"
//delay
delayQueue = "delay_queue"
delayExchange = "delay_exchange"
delayRouterKey = "delay_exchange"
prefix = "v1_prefix"
sep = "_"
eType = "F"
_ttl = 60 * 1000
)
var rabbitProduct1 = rabbit.NewRabbitProduct(addr,_ttl,prefix,sep,delayExchange,delayQueue,delayRouterKey)
// register recycle
go rabbitProduct1.InitDefdelay(false)
go rabbitProduct1.InitDefdelay(true)
go rabbitProduct1.RegisterDelayWithPreFix("delay_queue","delay_exchange","delay_exchange")
// ttl is dead recycle time if ttl > 0 then recycle
rabbitProduct1.PubMessage(true,eType,queue,exchange,routerKey,msg,rabbitProduct1.GetBool(1),rabbitProduct1.GetBool(0),_ttl)
}
希望它会帮助您或给您一些想法