「这是我参与2022首次更文挑战的第7天,活动详情查看:2022首次更文挑战」。
2.3 HelloWorld 模型
P代表生产者,C代表消费者,红色部分是队列。
生产者生成消息到队列中,消费者进行消费,直连单点模式。
2.3.1 生产者
- 声明连接对象
var ProductMQ *amqp.Connection
- 声明通道
ch, err := ProductMQ.Channel()
- 创建队列
q, err := ch.QueueDeclare("hello", // 队列名字
false, // 是否持久化,
false, // 不用的时候是否自动删除
false, // 用来指定是否独占队列
false, // no-wait
nil, // 其他参数
)
参数1(name):队列名字 参数2(durable):持久化,队列中所有的数据都是在内存中的,如果为true的话,这个通道关闭之后,数据就会存在磁盘中持久化,false的话就会丢弃 参数3(autoDelete):不需要用到队列的时候,是否将消息删除 参数4(exclusive):是否独占队列,true的话,就是只能是这个进程独占这个队列,其他都不能对这个队列进行读写 参数5(noWait):是否阻塞 参数6(args):其他参数
- 发布消息
body := "Hello World!"
err = ch.Publish(
"", // 交换机
q.Name, // 队列名字
false, // 是否强制性
// 当mandatory标志位设置为true时,如果exchange根据自身类型和消息routeKey无法找到一个符合条件的queue,那么会调用basic.return方法将消息返回给生产者
// 当mandatory设置为false时,出现上述情形broker会直接将消息扔掉
false, //当immediate标志位设置为true时,如果exchange在将消息路由到queue(s)时发现对于的queue上么有消费者,那么这条消息不会放入队列中。当与消息routeKey关联的所有queue(一个或者多个)都没有消费者时,该消息会通过basic.return方法返还给生产者
// 是否立刻
/**
概括来说,mandatory标志告诉服务器至少将该消息route到一个队列中,否则将消息返还给生产者;immediate标志告诉服务器如果该消息关联的queue上有消费者,则马上将消息投递给它,如果所有queue都没有消费者,直接把消息返还给生产者,不用将消息入队列等待消费者了。
**/
amqp.Publishing{
ContentType: "text/plain",
Body: []byte(body), // 发送的消息
})
参数1(exchange):交换机,后续会讲到 参数2(route-key):队列名字 参数3(mandatory):是否强制性,
当mandatory标志位设置为true时,如果exchange根据自身类型和消息routeKey无法找到一个符合条件的queue,那么会调用
basic.return方法将消息返回给生产者 当mandatory设置为false时,出现上述情形broker会直接将消息扔掉
参数4(immediate):是否立即处理
当immediate标志位设置为true时,如果exchange在将消息路由到queue(s)时发现对于的queue上么有消费者,那么这条消息不会放入队列中。当与消息routeKey关联的所有queue(一个或者多个)都没有消费者时,该消息会通过basic.return方法返还给生产者
也就是说,mandatory 标志告诉服务器至少将该消息route到一个队列中,否则将消息返还给生产者;immediate标志告诉服务器如果该消息关联的queue上有消费者,则马上将消息投递给它,如果所有queue都没有消费者,直接把消息返还给生产者,不用将消息入队列等待消费者了。
参数5(msg):发布的消息,ContentType是传输类型,Body是发送的消息。
2.3.2 消费者
- 声明通道
ch, err := ConsumerMQ.Channel()
- 创建队列
q, err := ch.QueueDeclare(
"hello",
false,
false,
false,
false,
nil,
)
- 读取队列消息
msgs, err := ch.Consume(
q.Name,
"",
true,
false,
false,
false,
nil,
)
由于消费者端需要一直监听,所以我们要用一个for循环+channel去阻塞主进程,使得主进程一直处于监听状态。
forever := make(chan bool)
go func() {
for d := range msgs {
fmt.Printf("Received a message: %s", d.Body)
}
}()
fmt.Printf(" [*] Waiting for messages. To exit press CTRL+C")
<-forever
2.3.3 结果
- 生产者
- 消费者