Go RabbitMQ (一)

  • 生产者:生产者是负责发送消息的
  • 队列:队列是RabbitMQ用来存储消息的,受主机内存和磁盘大小的限制,本质上是一个消息的缓冲区。生产者可以将消息发送至队列中,消费者可以从队列中接收到消息
  • 消费者:消费者是用来等待接收消息

生产者,消费者,代理可以驻留在不同主机或同一主机,一个应用可以是生产者也可以是消费者

 

 

第一部分   常用操作函数

生产者

 

1.连接RabbitMQ

conn,err := amqp.Dial("amqp://guest:guest@localhost:5672/")
if err != nil {
    log.Fatal(err)
}
defer conn.Close()

RabbitMQ的连接已经为我们抽象了socket的连接,同时为我们处理了协议版本号和身份认证等等

 

2.创建通道

ch,err := conn.Channel()
if err != nil {
    log.Fatal(err)
}
defer ch.Close()

在使用其他API完成任务的时候我们首先通过以上方式创建通道

 

3.声明队列并发送数据

在开始发送消息之前我们首先应该声明一个队列。声明队列之后我们就可以将消息发送至队列当中

q, err := ch.QueueDeclare(
"hello", // name
false,   // durable
false,   // delete when unused
false,   // exclusive
false,   // no-wait
nil,     // arguments
)

说明: 其中durable设为true则queue持久化,否则不会做持久化。
if err != nil { log.Fatal(err) } body := "Hello World!"
err = ch.Publish( "", // exchange q.Name, // routing key false, // mandatory false, // immediate amqp.Publishing { ContentType: "text/plain", Body: []byte(body), }) if err != nil { log.Fatal(err) }

说明:
其中amqp.Publishing的DeliveryMode如果设为amqp.Persistent则消息会持久化。
需要注意的是如果需要消息持久化Queue也是需要设定为持久化才有效

队列的声明是一个幂等性操作,如果不存在该队列的话则会创建。此处注意,如果队列存在,修改了队列参数并不会影响已经存在的队列,并且会返回错误。消息内容是一个字节数组,所以我们必须进行编码

 

接收者:

连接,创建通道,队列

在接收端我们同样需要像发送端一样连接RabbitMQ,创建通道后再创建队列,注意此处队列的创建是跟发送端的队列完全匹配的。队列在接收端也创建是因为我们接收端有可能比发送端先启动,所以为了保证我们要消费的队列存在我们在此处也进行创建

 

1.消费消息

msgs, err := ch.Consume(
q.Name, // queue
"",     // consumer
true,   // auto-ack
false,  // exclusive
false,  // no-local
false,  // no-wait
nil,    // args
)
if err != nil {
    log.Fatal(err)
}   
forever := make(chan bool)
go func() {
for d := range msgs {
log.Printf("Received a message: %s", d.Body)
}
}()
log.Printf(" [*] Waiting for messages. To exit press CTRL+C")
<-forever

 

 

 

第二部分  消费者消息应答模式

 

1.

接收消息

msgs, err := ch.Consume(
                q.Name,
                "MsgWorkConsumer",
                false,  //Auto Ack
                false,
                false,
                false,
                nil,
            )

其中Auto ack可以设置为true。如果设为true则消费者一接收到就从queue中去除了,如果消费者处理消息中发生意外该消息就丢失了。
如果Auto ack设为false。consumer在处理完消息后,调用msg.Ack(false)后消息才从queue中去除。即便当前消费者处理该消息发生意外,只要没有执行msg.Ack(false)那该消息就仍然在queue中,不会丢失。

生成的Queue在生成是设定的参数,下次使用时不能更改设定参数,否则会报错

 

posted @ 2020-02-12 09:06  风一样自由419154  阅读(4587)  评论(0编辑  收藏  举报