Python云计算框架:OpenStack源码分析之RabbitMQ(二)

之前发布的文章因为在编辑后代码部分在手机上看不清已被及时删除,本文重新编辑好之后再发布一次,带来不便请谅解!

專 欄

ZZR,Python中文社区专栏作者,OpenStack工程师,曾经的NLP研究者。主要兴趣方向:OpenStack、Python爬虫、Python数据分析。

Blog:http://skydream.me/

CSDN:http://blog.csdn.net/titan0427/article/details/50365480

fanout exchange

在上一篇中,task_queue所解决的问题是,一个message只能被一种consumer所接收。现在我们有了新的需求,我们需要一个日志系统,我们希望有两种consumer,一种consumer将日志输出到屏幕,另一种consumer写到disk。为了实现这个目的,我们希望message被投到两个queue中,交给不同的consumer进行处理。如下所示:

对于producer,不再指定哪一个queue来接收消息,而是哪一个exchange来接收消息。exchange不保存信息,如果没有queue绑定在这个exchange上的话,消息就丢失了。代码如下:

对于consumer,自己创建临时queue(exclusive=True,当这个consumer终止,这个queue就销毁),将这个queue接到exchange上,然后通过这个queue接收exchange发出的消息:

如下图所示,每一个consumer都建了自己的临时queue,并与exchange进行了绑定:

direct exchange

上面的例子中,queue_bind()的时候我们没有指定routing_key(为了避免混淆,后续将其称为binding_key)。binding_key的功能与exchange的类型有关。对于fanout exchange而言,binding_key没有意义。对于direct exchange而言,如下图所示,只有消息的routing_type与queue的binding_key相同时才会发送到该queue:

可以指定相同的binding_key,如下图所示:

借此,我们可以将日志系统改造为以下模式,不同的consumer只接收特定类型的日志信息:

完整代码如下:

topic exchang

topic exchange与direct exchange类似,只是它允许binding_key使用特殊字符(注意,特殊字符代表的是单词,不是字母):

- *:代表一个单词 - #:代表零个或多个单词

比如下面这个例子。routing_key定义为"<celerity>.<colour>.<species>"。举几个routing_key匹配的例子: - quick.orange.rabbit:一,二 - lazy.orange.elephant:一,二 - quick.orange.fox:一 - lazy.brown.fox:三 - lazy.pink.rabbit:二,三(但只发一次,因为二和三是同一个队列) - quick.brown.fox:无,舍弃 - orange:无,舍弃 - quick.orange.male.rabbit:无,舍弃 - lazy.orange.male.rabbit:三

当binding_key不使用这些特殊字符时,topic exchange其实就是direct exchange;当binding_key使用#时,topic exchange其实就是fanout exchange,也就是所有消息都接收。

一些极端的例子: binding_key:*,routing_key:空串。不匹配。 binding_key:#.*,routing_key:..。匹配。 binding_key:#.*,routing_key:apple。匹配。

完整代码:

总结

在上一篇中:

再回顾一下上面的代码。首先明确,这种情况使用的是默认exchange。对于producer,它将消息交给exchange,然后exchange通过routing key来判断要将消息交到哪个queue。实际上相当于将消息直接发送到queue中。而consumer直接指定queue的名字,也就是它直接绑定到这个queue。这个过程中exchange其实没什么存在感。

而这一篇,实际上producer只认exchange。它只负责将消息交给exchange。consumer自己搭建queue,将queue绑定到它感兴趣的exchange上。exchange决定它以什么样的形式提供服务,是fanous还是direct。

原文发布于微信公众号 - Python中文社区(python-china)

原文发表时间:2017-01-21

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

发表于

我来说两句

0 条评论
登录 后参与评论

相关文章

来自专栏一枝花算不算浪漫

[Redis]Redis 概述及基本使用规范.

52980
来自专栏技术小讲堂

WCF中操作的分界于调用顺序和会话的释放操作分界实例停止

操作分界 在WCF操作契约的设计中,有时会有一些调用顺序的业务,有的操作不能最先调用,有的操作必须最后调用,比如在从一个箱子里拿出一件东西的时候,必须先要执行打...

34360
来自专栏竹清助手

NodeJS错误处理最佳实践

NodeJS的错误处理让人痛苦,在很长的一段时间里,大量的错误被放任不管。但是要想建立一个健壮的Node.js程序就必须正确的处理这些错误,而且这并不难学。如果...

29430
来自专栏PHP实战技术

PHP ob_start() 函数介绍

php ob_start 与 ob_end_flush() 是 php 的缓冲输出函数。

42290
来自专栏前端侠2.0

Angular技巧汇总 原

    声明项目的全局类型,同时不需要在各个Ts文件中import {XXX} from 'xxx'  ,就能直接引用!方法是:

13120
来自专栏嵌入式程序猿

Polyspace不认识Interrupt,肿么办?

曾经在公众号中介绍过优秀的软件验证工具Polyspace,有好多猿友在交流群里咨询这个软件的问题,今天我们就典型的如何处理中断来给大家介绍下。 ...

31640
来自专栏阿杜的世界

Spring Boot:定制URL匹配规则

构建web应用程序时,并不是所有的URL请求都遵循默认的规则。有时,我们希望RESTful URL匹配的时候包含定界符“.”,这种情况在Spring中可以称之为...

15230
来自专栏马涛涛的专栏

异步与回调/函数的作用域链

程序里面所有的任务,可以分成两类:同步任务(synchronous)和异步任务(asynchronous)。

16940
来自专栏FreeBuf

Java反序列化漏洞从理解到实践

一、前言 在学习新事物时,我们需要不断提醒自己一点:纸上得来终觉浅,绝知此事要躬行。这也是为什么我们在学到知识后要付诸实践的原因所在。在本文中,我们会深入分析大...

337100
来自专栏along的开发之旅

Java8移除永久代

最近看深入理解Java虚拟机, 在实战OutOfMemoryError的运行时常量池溢出时, 我的Intellij提示如下:

12610

扫码关注云+社区

领取腾讯云代金券