设为首页 收藏本站
查看: 1099|回复: 0

[经验分享] RabbitMQ fanout广播模式

[复制链接]

尚未签到

发表于 2017-12-8 22:32:12 | 显示全部楼层 |阅读模式
一、消息公平分发
  如果Rabbit只管按顺序把消息发到各个消费者身上,不考虑消费者负载的话,很可能出现,一个机器配置不高的消费者那里堆积了很多消息处理不完,同时配置高的消费者却一直很轻松。为解决此问题,可以在各个消费者端,配置perfetch=1,意思就是告诉RabbitMQ在我这个消费者当前消息还没处理完的时候就不要再给我发新消息了。
   DSC0000.png



channel.basic_qos(prefetch_count=1)

   注:在消费之前加
DSC0001.png


二、fanout广播模式
  之前的例子都基本都是1对1的消息发送和接收,即消息只能发送到指定的queue里,但有些时候你想让你的消息被所有的Queue收到,类似广播的效果,这时候就要用到exchange了,先来说说exchange的官方说明:
  An exchange is a very simple thing. On one side it receives messages from producers and the other side it pushes them to queues. The exchange must know exactly what to do with a message it receives. Should it be appended to a particular queue? Should it be appended to many queues? Or should it get discarded. The rules for that are defined by the exchange type.
  Exchange在定义的时候是有类型的,以决定到底是哪些Queue符合条件,可以接收消息


  • fanout:所有bind到此exchange的queue都可以接收消息(纯广播的,所有消费者都能收到消息)
  • direct:通过routingKey和exchange决定的那个唯一的queue可以接收消息
  • topic:所有符合routingKey(此时可以是一个表达式)的routingKey所bind的queue可以接收消息
  • headers:通过headers 来决定把消息发给哪些queue(这个很少用,一般情况下,我们用不到)

2.1、fanout广播模式
  说明:fanout这种模式是所有绑定exchange的queue都可以接收到消息。exchange=>转换器
  1、生产者(fanout_publiser)
  说明:跟之前写的不同,生产者这边并没有声明queue,因为生产者是以广播的形式,所以这边不需要声明queue



import pika

#创建socket连接
connection = pika.BlockingConnection(pika.ConnectionParameters
(host='localhost'))
#创建管道
channel = connection.channel()

#声明exchange,且exchange的名字是logs,exchange的类型为fanout
channel.exchange_declare(exchange='logs',exchange_type="fanout")

#发送的消息
message = "info:hello world"

#生产一个消息
channel.basic_publish(
exchange="logs",
routing_key='',
body=message
)
print("[X] Send {0}".format(message))

#关闭连接
connection.close()

  注:这边的exchange的名字logs是随便起的
  2、消费者(fanout_consumer)
  说明:消费者这边要声明一个唯一的queue_name的对象,并且从对象中获取queue名



import pika
#创建一个socket
connection = pika.BlockingConnection(pika.ConnectionParameters(
host="localhost"))
#创建一个管道
channel = connection.channel()
#声明exchange,exchange的名字logs,类型是fanout广播模式
channel.exchange_declare(exchange="logs",
exchange_type="fanout")
#不指定queue名字,rabbit会随机分配一个名字,exclusive=True会在使用此queue的消费者断开后,自动将queue删除,result是queue的对象
result = channel.queue_declare(exclusive=True) #exclusive=>排他的,唯一的
#获取queue名
queue_name = result.method.queue
#绑定exchange
channel.queue_bind(exchange="logs",
queue=queue_name)

print('
  • Waiting for logs. To exit press CTRL+C')
    #声明回调函数
    def callback(ch,method,properties,body):
    "回调函数"
    print("[X] {0}".format(body))
    #消费者消费
    channel.basic_consume(callback,
    queue=queue_name,
    no_ack=True)
    #启动消费模式
    channel.start_consuming()

      3、代码逻辑图
       DSC0002.png
      3、web消息图
    DSC0003.png

      ①服务端没有声明queue,为什么客户端要声明一个queue?
      答:生产者发消息到exchange上,exchange就会遍历一遍,所有绑定它的哪些queue,然后把消息发到queue里面,它发了queue就不管了,消费者从queue里面去收,所以就收到广播了,而不是说exchange直接就把消息发给消费者,消费者只会从queue里去读消息,且拿着queue去绑定exchange。
      ②为什么queue要自动生成,而不是自己手动去写?
      答:我这个queue只是为了收广播的,所以如果我消费者不收了,这个queue就不需要了,所以就让它自动生成了,不需要的了,就自动销毁

    2.2、广播实时性
      广播是实时的,你不在的时候,就是你消费者没有开启的时候,发消息的时候,就没有收到,这个时候就没有了。如果消费者开启了,生产者发消息时,消费者是收的到的,这个又叫订阅发布,收音机模式

  • 运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
    2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
    3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
    4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
    5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
    6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
    7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
    8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

    所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-422276-1-1.html 上篇帖子: Cannot save rules; there is insufficient space 下篇帖子: day11-RabbitMQ fanout广播模式
    您需要登录后才可以回帖 登录 | 立即注册

    本版积分规则

    扫码加入运维网微信交流群X

    扫码加入运维网微信交流群

    扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

    扫描微信二维码查看详情

    客服E-mail:kefu@iyunv.com 客服QQ:1061981298


    QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


    提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


    本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



    合作伙伴: 青云cloud

    快速回复 返回顶部 返回列表