golang rabbitmq消费者设计_RabbitMQ系列笔记广播模式和路由模式

c1fa7c29558ddb7cb5b74ca9c7841858.png

导语

上一节介绍了简单的工作模式,即一个队列可以被多个消费者进行消费,只有一条消息被送到消费者,采用公平调度的方式,在以往的例子中似乎我们还没用到交换器进行发送消息,我们都知道,往队列里发送消息,是需要用交换器进行分发的消息的,为什么我们没有申请交换器仍然可以发送消息呢?因为在RabbitMQ服务器中,如果不申请交换器,服务器会使用默认的交换器,所以说,交换器在发送消息的时候必不可少,今天我们学习两种交换器分别为fanout(扇形交换器)和direct(直连交换器)

扇形交换器(日志记录器)

特性

分发消息到与之绑定的所有队列,发送消息到交换器时会忽略routing key(路由),我们可以称它为广播消息。

生产者

申请交换器

  • 指定交换器的名字
  • 指定交换器的类型
1err = ch.ExchangeDeclare(
2    "logs",   //交换器的名字
3    "fanout", //交换器的类型、这里为广播类型
4    true,     //是否持久
5    false,    //无用的时候是否自动删除
6    false,    //true表示是。客户端无法直接发送msg到内部交换器,只有交换器可以发送msg到内部交换器。
7    false,    //no-wait
8    nil,      //arguments
9)

发送消息

生产者制制定了交换器后就可以直接发送消息了

 1err = ch.Publish(
 2    "logs", //发送到交换机的名字
 3    "",     // 路由,即队列的名字
 4    false,  //mandatory
 5    false,  //immediate
 6    amqp.Publishing{
 7        DeliveryMode: amqp.Persistent, //消息的持久化
 8        ContentType:  "text/plain",
 9        Body:         []byte(body),
10    },
11)

消费者

申请交换器

消费者申请交换器需要和生产者完全保持一致。

1err = ch.ExchangeDeclare(
2    "logs",   //交换器的名字
3    "fanout", //交换器的类型、这里为广播类型
4    true,     //是否持久
5    false,    //无用的时候是否自动删除
6    false,    //true表示是。客户端无法直接发送msg到内部交换器,只有交换器可以发送msg到内部交换器。
7    false,    //no-wait
8    nil,      //arguments
9)

申请队列

在消费者申请队列时,因为这个案例负责记录日志,而日志可以从多个生产者进行产生,因此我们用一个临时队列存储,不需要进行持久化。

1q, err := ch.QueueDeclare(
2    "",    //name
3    false, //durable
4    false, //delete when usused
5    true,  // exclusive
6    false, //no-wait
7    nil,   // arguments
8)

队列绑定

队列需要选择交换器,来收消息

1err = ch.QueueBind(
2    q.Name, //队列的名字
3    "",     //routing key
4    "logs", //所绑定的交换器
5    false,
6    nil,
7)

运行

我们启动两个消费者一个生产者,生产者发送一条消息,这两个消费者会同时收到该消息

777c5d32f3a02349411918b2934ffd6d.png

520476def73a6832efd0926f36a4c105.png

直连交换器(路由模式)

对于上面的案例,可能有的同学会想,我如果不想让所有的消费者收到消息,只想订阅我的消费者收到消息,订阅路由不同,消息会发送到不同的消费者不是更好吗,因此我们需要用direct交换器进行分发消息

生产者

申请交换器

1err = ch.ExchangeDeclare(
2    "logs_direct", //交换器的名字
3    "direct",      //交换器的类型、这里为广播类型
4    true,          //是否持久
5    false,         //无用的时候是否自动删除
6    false,         //true表示是。客户端无法直接发送msg到内部交换器,只有交换器可以发送msg到内部交换器。
7    false,         //no-wait
8    nil,           //arguments
9)

发送消息

生产者发送消息的时候需要指定路由

 1err = ch.Publish(
 2    "logs_direct", //发送到交换机的名字
 3    "info",        // 路由,
 4    false,         //mandatory
 5    false,         //immediate
 6    amqp.Publishing{
 7        DeliveryMode: amqp.Persistent, //消息的持久化
 8        ContentType:  "text/plain",
 9        Body:         []byte(body),
10    },
11)

消费者

申请交换器

1err = ch.ExchangeDeclare(
2    "logs_direct", //交换器的名字
3    "direct",      //交换器的类型、这里为广播类型
4    true,          //是否持久
5    false,         //无用的时候是否自动删除
6    false,         //true表示是。客户端无法直接发送msg到内部交换器,只有交换器可以发送msg到内部交换器。
7    false,         //no-wait
8    nil,           //arguments
9)

申请队列

1q, err := ch.QueueDeclare(
2    "",    //name
3    false, //durable
4    false, //delete when usused
5    true,  // exclusive
6    false, //no-wait
7    nil,   // arguments
8)

队列绑定

治理需要注意的是,绑定时不仅要指定路由还要指定交换器

1err = ch.QueueBind(
2    q.Name,        //队列的名字
3    "info",        //routing key
4    "logs_direct", //所绑定的交换器
5    false,
6    nil,
7)

运行

为了更好的进行演示,我们需要开启3个消费者,在代码中只需要更改路由的名称,两个消费者的路由一样,另一个不一样,两个生产者发送消息,路由不同,我们会看到下面不同的控制台,有两个消费者一致的消息,另一个不一样。

8e99ea80ff0fe08166d6573ee0c65291.png

当我们结束程序的时,最终看我们的可视化界面,我们的队列也被删除了

8560e2cb1dffae645069c6cd46a9a330.png

推荐阅读

  • 开发环境搭建(持续更新中)
  • RabbitMQ系列笔记介绍篇
  • Golang中Modle包的使用
  • goriila context深入学习笔记
  • Go Context深入学习笔记
  • 基于Nginx和Consul构建高可用及自动发现的Docker服务架构
  • 关于log日志的深入学习笔记

本文欢迎转载,转载请联系作者,谢谢!

  • 公众号【常更新】:无崖子天下无敌
  • GitHub:https://github.com/yuwe1
  • CSDN【看心情更新】: https://blog.csdn.net/weixin_40051278
  • 博客地址【定期更新】:https://mowuya.cn/

68deaa1f47c497c211babe51363a0cb8.png
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值