RabbitMQ学习笔记(四)

发布/订阅

ps: 使用pika python客户端
前面学习了搭建工作队列,每一个任务只是分发给了一个工作者。但是现在我想实现将一个消息分发给多个消费者。就是设计模式中的"观察者模式"--发布/订阅。

为了描述这种模式,构件一个简单的日志系统。包括两个程序--第一个程序负发送日志消息,第二个程序负责获取消息并输出内容。

在日志系统中,所有运行的接收方程序都会接收消息,我们让其中一个接收者将日志写入磁盘,另一个接收者将日志输出到屏幕上。日志消息是被广播到所有的接收者。

交换机####

分析前面的教程:

  • 发布者(producer)是发布消息的应用程序
  • 队列(queue)用于消息的存储
  • 消费者(consumer)是接受消息的应用程序。
    RabbitMQ其实不是直接将消息发送到队列中去,事实上,发布者是将消息交给excheng(交换机)。交换机一边从消息发布方接收消息,一边将消息推送到队列。交换机必须知道如何处理他所接收的消息,是应该推送到指定的队列还是多个队列,或者直接忽视消息。这些规则是有交换机的类型来决定。

RabbitMQ提供几种类型的交换机可供选择:

Item name
直连交换机 direct exchange
扇型交换机 fanout exchange
主题交换机 topic exchange
头交换机 headers exchange

我们使用一下方法来创建一个扇型交换机

channel.exchange_declare(exhcang='logs', type='fanout')

Fanout exchange将所有生产者发送到本交换机上的消息全部像风扇转动,将所有的消息发给所有的队列。

匿名交换机

前面我们没有提到减缓及,但是仍然能够将消息发送到队列中。因为我们使用了命名为空字符串的默认交换机。

channel.basic_publish(echange='',
  routing_key='hello',
  body=message)

exchange参数就是交换机的名字,空字符串表示匿名交换机,消息将发送到指定的routing_key指定的队列。
我们可以发送一个消息到一个具名的交换机

channel.basic_publish(exchange='logs',
  routing='',
  body=message)

在扇型交换机中,routing_key是不需要的。

临时队列

队列的名字可以由我们手动创建,但是也可以使用系统给我们创建一个随机的队列名字。只需要在创建队列的函数中加上参数就可以。

result = channel.queue_declare(exclusive=True)

这样就可以创建一个匿名队列(形式为amq.gen-*),我们可以通过result.method.queue来获取这个随机的队列名。当消费者断开连接的时候吗,这个队列就会被立即删除。

绑定(bindings)


我们创建一个扇型交换机和一个队列,现在需要告诉交换机如发送消息给我们的队列,交换机和队列之间的关系叫做绑定(binding)

channel.queue_bind(exchange='logs',
  queue=result.method.queue)

现在,logs交换机将会把消息添加到我们的队列中。

Coding

emit_log.py

import pika
import sys

connection = pika.BlockingConnection(pika.ConnectionParameters(
        host='localhost'))
channel = connection.channel()

channel.exchange_declare(exchange='logs',
                         type='fanout')

message = ' '.join(sys.argv[1:]) or "info: Hello World!"
channel.basic_publish(exchange='logs',
                      routing_key='',
                      body=message)
print " [x] Sent %r" % (message,)
connection.close()

我们创建了一个fanout类型的交换机,发送消息时将消息发送到这个交换机上。
receives_logs.py

import pika

connection = pika.BlockingConnection(pika.ConnectionParameters(
        host='localhost'))
channel = connection.channel()

channel.exchange_declare(exchange='logs',
                         type='fanout')

result = channel.queue_declare(exclusive=True)
queue_name = result.method.queue

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] %r" % (body,)

channel.basic_consume(callback,
                      queue=queue_name,
                      no_ack=True)

channel.start_consuming()
  • 消费者创建了一个fanout类型的交换机,这里重复创建是如果消费者程序先运行,不创建交换机,是不允许将消息发送到一个不存在的交换机的。
  • 消费者创建了一个匿名队列,然后将这个匿名队列和交换机进行bind。
  • 消费者等待从绑定的交换机队列中获取消息。
    打开两个终端一个终端将日志保存到日志文件;另一个将日志输出到屏幕上。
$ python receive_logs.py > logs_from_rabbit.log

这个终端运行的消费者将log信息打印出来

$ python receive_logs.py

发送日志信息:

$ python emit_log.py

使用rabbitmqctl list_bindings可以查看已经创建的队列绑定

$ sudo rabbitmqctl list_bindings
Listing bindings ...
 ...
logs    amq.gen-TJWkez28YpImbWdRKMa8sg==                []
logs    amq.gen-x0kymA4yPzAT6BoC/YP+zw==                []
...done.

显示我们创建的两个匿名队列都绑定到了fanout类型交换机logs上面。

待续。。。

参考文章http://rabbitmq.mr-ping.com/tutorials_with_python/[3]Publish_Subscribe.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 204,189评论 6 478
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,577评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,857评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,703评论 1 276
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,705评论 5 366
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,620评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,995评论 3 396
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,656评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,898评论 1 298
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,639评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,720评论 1 330
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,395评论 4 319
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,982评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,953评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,195评论 1 260
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 44,907评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,472评论 2 342

推荐阅读更多精彩内容

  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 134,594评论 18 139
  • 来源 RabbitMQ是用Erlang实现的一个高并发高可靠AMQP消息队列服务器。支持消息的持久化、事务、拥塞控...
    jiangmo阅读 10,343评论 2 34
  • RabbitMQ笔记 本文参考资料:http://blog.csdn.net/chwshuang/article/...
    wangxiaoda阅读 2,811评论 0 11
  • 什么叫消息队列 消息(Message)是指在应用间传送的数据。消息可以非常简单,比如只包含文本字符串,也可以更复杂...
    lijun_m阅读 1,335评论 0 1
  • 发布/订阅 在上一个教程中我们创建了一个工作队列。如果说工作队列是将一个任务完全分发给一个消费者。在这部分,我们所...
    番薯IT阅读 5,021评论 0 1