RabbitMQ工业级的消息队列服务器。

兔子和兔子窝

动机来源:从生产环境的电子邮件处理流程当中分支出一个特定的离线分析流程。

解决方案1:

开始使用MySQL处理,将要处理的东西放在表里面,另一个程序从中读取。

需要多个程序从一个队列中取数据来处理?硬编码程序的个数。

如果能够允许程序动态地增加和减少的时候动态进行压力分配?

解决方案2:

消息队列

现有的Queue

1、Apache ActiveMQ 可能会造成消息丢失,不可接受

2、ZeroMQ和RabbitMQ都支持一个开源的消息协议,成为AMQP.

AMQP的一个优点是它是一个灵活和开放的协议,以便和另外两个商业化的MessageQueue竞争。

3、ZeroMQ不支持消息持久化和崩溃恢复,不太好,但是如果不在意消息持久化和崩溃恢复,可以试试,延迟很低,而且支持灵活的拓扑

4、RabbitMQ可以支持消息持久化以及崩溃恢复

RabbitMQ

RabbitMQ是基于Erlang写的。在Erlang中,充斥着大量轻量进程,它们之间使用消息传递通信。和消息队列的思路一致。

RabbitMQ支持持久化。如果RabbitMQ死掉,消息并不会丢失,当队列重启,一切都会回来。

可以和Python无缝结合,提供对应的库http://barryp.org/software/py-amqplib/

AMQP

AMQP当中有四个概念非常重要:虚拟主机(virtual host),交换机(exchange),队列(queue)和绑定(binding)。

一个虚拟主机持有一组交换机、队列和绑定。

为什么需要多个虚拟主机?RabbitMQ当中,用户只能在虚拟主机的粒度进行权限控制。因此,如果需要禁止A组访问B组的交换机/队列/绑定,必须为A和B分别创建一个虚拟主机。每一个RabbitMQ服务器都有一个默认的虚拟主机"/"。

交换机、队列以及绑定

队列

队列是消息的重点,可以理解伪装消息的容器。消息就一直在里面,直到有客户端(也就是消费者,Consumer)连接到这个队列并且将其取走为止。

队列是由消费者(Consumer)通过程序建立的,不是通过配置文件或者命令行攻击的。

如果一个消费者试图创建一个已经存在的队列,RabbitMQ会忽略这个请求。因此可以将消息队列的配置写在应用程序的代码里面。

当已经创建并且连接到队列,消费者程序等待消息到来。当然需要把一个消息放进队列中,这里需要一个交换机(Exchange)

交换机

交换机可以理解成具有路由表的路由程序,仅此而已。每个消息都有一个称为路由键(routing key)的属性,就是一个简单的字符串。交换机当中有一系列的绑定(binding),即路由规则(routes)。例如指明具有路由键的X消息要到名为X_Queue队列中。

消费者程序要负责创建交换机们(Exchanges)?为什么是可以有多个交换机?

原因:每个交换机在自己独立的进程当中执行,因此增加多个交换机就是增加多个进程,可以充分利用服务器上的CPU核以便到达更高的效率。

在RabbitMQ的集群当中,可以使用类似的思路来扩展交换机以便获取更高的吞吐量。

已经有了消息,不知道往哪个队列中发送,需要指定路由规则,即绑定。

绑定(binding)

一个绑定就是一个类似这样的规则:将交换机desert当中具有路由键“阿里巴巴”的消息送到队列hideout里面去。

一个绑定就是一个基于路由键routing_key将交换机和队列连接起来的路由规则。

如果需要将同一个消息发送到两个不同的队列中,就需要创建两个绑定,每个都连接一个交换机和一个队列。

在这种情况下,交换机会复制一份消息并且把它们分别发送到两个队列当中。交换机就是一个由绑定构成的路由表。

交换机有多种类型,都是做路由的,不过接受不同类型的绑定。

为什么不创建一种交换机来处理所有类型的路由规则呢?因为每种规则用来做匹配分子的CPU开销是不同的。

Fanout Exchange:不处理路由键,只需要简单地将队列绑定到交换机上。一个发送到交换机的消息都会被转发到与该交换机绑定的所有队列上。Fanout交换转发消息是最快的,因为不需要任何中间处理。

Direct Exchange:处理路由键。需要将一个队列绑定到交换机上,要求该消息与一个特定的路由键完全匹配。

Topic Exchange:将路由键和某种模式进行匹配。此时队列需要绑定在一个模式上。

符号"#"匹配一个或多个词,符号"*"匹配不多不少一个词。例如“audit.#”能够匹配"audit.irs.corporate",但是"audit.*"只会匹配到"audit.irs"

其他类型的图,参照http://www.cnblogs.com/gsblog/p/3823426.html

持久化

如果使用默认参数构造的话,在RabbitMQ服务器程序挂了后,队列、交换机和绑定都没有了。

RabbitMQ重启后会清空一切,如何避免这一切。

队列和交换机有一个创建时候指定的标志durable。durable的唯一含义就是具有这个标志的队列和交换机会在重启之后重新建立,它不表示说在队列当中的消息会在重启后恢复。

那么如何才能做到不只是队列和交换机,还有消息都是持久化的呢?

首先一个问题是,真的需要消息是持久化的吗?对于一个需要在重启之后回复的消息来说,需要被写入到磁盘上,而即使最简单的磁盘操作也是要消耗时间的。如果和消息的内容相比,更看重的是消息处理速度,那么不要使用持久化的消息。对于其他服务来说,持久化可能很重要。

当将消息发布到交换机的时候,可以指定一个标志"delivery mode"(投递模式)。各个AMQP库不同,指定这个标志的方法可能不一样。Python中是将deliver mode设置为2,表示持久化。一般的AMQP默认是将deliver mode设置成1,就是非持久化的。

持久化消息的步骤如下:

1、将交换机设置成durable

2、将队列设置称durable

3、将消息的delivery mode设置成2

绑定怎么办?

无法在创建绑定的时候设置durable。没有问题,如果绑定一个durable的队列和一个durable的交换机,RabbitMQ会自动保留这个绑定。类似,如果删除某个队列或交换机(无论是否durable),依赖它的绑定都会自动删除。

注意两点:

1、RabbitMQ不允许绑定一个non-durable的交换机和一个durable的队列。反之亦然,要想成功必须队列和交换机都是durable的。

2、一旦创建队列和交换机,就不能修改其标志的。例如创建一个nondurable的队列,然后想把它修改称durable的,唯一的办法就是删除这个队列然后重现创建。

例子

需要一个python的AMQP库

1、py-amqlib——通用的AMQP

2、txAMQP——使用Twisted框架的AMQP,因此允许异步IO

3、pika

参照之前的前几篇博客

参考链接

1、http://blog.ftofficer.com/2010/03/translation-rabbitmq-python-rabbits-and-warrens/

2、http://blogs.digitar.com/jjww/2009/01/rabbits-and-warrens/

3、http://www.ituring.com.cn/article/4669

【RabbitMQ+Python入门经典】兔子和兔子窝 笔记的更多相关文章

  1. [转][RabbitMQ+Python入门经典] 兔子和兔子窝

    [转][RabbitMQ+Python入门经典] 兔子和兔子窝 http://blog.csdn.net/linvo/article/details/5750987 RabbitMQ作为一个工业级的消 ...

  2. [RabbitMQ+Python入门经典] 兔子和兔子窝

    原文联接: http://blogs.digitar.com/jjww/2009/01/rabbits-and-warrens/ RabbitMQ作为一个工业级的消息队列服务器,在其客户端手册列表的P ...

  3. Python入门经典. 以解决计算问题为导向的Python编程实践

    Python入门经典. 以解决计算问题为导向的Python编程实践(高清版)PDF 百度网盘 链接:https://pan.baidu.com/s/1juLsew8UiOErRheQPOuTaw 提取 ...

  4. python入门经典_好资源送不停

    Python入门经典(2K超清_送书) https://study.163.com/course/courseMain.htm?courseId=1006183019&share=2& ...

  5. Python入门经典练习题

    [程序1] 题目:有1.2.3.4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? num_list=[]cou=0for i in range(1,5): for j in range( ...

  6. python基础入门教程《python入门经典》

    第一章 在python中使用数字 1.用变量存储信息 1.1变量的类型 变量,用于存储很多不同的数据类型的信息. 基本数据类型 数据类型 存储内容 示例 integer 整   float 浮点   ...

  7. Python入门经典 以解决计算问题为导向的Python编程 待完好

    1.4.2:python将代码分为两类:表达式和语句  表达式和语句::  表达式(值和运算符的结合,将产生新值--返回值. 假设在python shell中输入表达式将显示返回值.也就是说,假设x的 ...

  8. Python入门经典案例一

    # 有1.2.3.4个数字,能组成多少个互不相同且无重复数字的三位数?都是多少? sum = 0 values = range(1, 5) for i in values: for j in valu ...

  9. Python 的经典入门书籍

    实python非常适合初学者入门,上手很容易.我就是完全通过网上资源学了python的.最大的是3点经验:1.找一本浅显易懂,例程比较好的教程,从头到尾看下去.不要看很多本,专注于一本.把里面的例程都 ...

随机推荐

  1. doubi -- 初创

    doubi -- 初创 [背景分析] 一直在苦苦探寻人生的价值和意义.在这"二八"年华,对IT工作有点厌倦了.每天都是无休止地问题定位,需求会议.碎片化的时间写出来的代码都是无比的 ...

  2. Python 并发编程(一)之线程

    常用用法 t.is_alive() Python中线程会在一个单独的系统级别线程中执行(比如一个POSIX线程或者一个Windows线程)这些线程将由操作系统来全权管理.线程一旦启动,将独立执行直到目 ...

  3. IDoc 基础知识

    Application Link Enabling ALE主要为了分布式业务系统而设计的.它可以使业务流程中的每个步骤分布在不同的SAP系统上,系统间可以通过IDoc交互数据.IDoc可以认为是个信封 ...

  4. JMS 基础

    1. JMS基本概念 JMS(Java Message Service) 即Java消息服务.它提供标准的产生.发送.接收消息的接口简化企业应用的开发. 它支持两种消息通信模型:点到点(point-t ...

  5. ModelForm

    这是一个神奇的组件,通过名字我们可以看出来,这个组件的功能就是把model和form组合起来,对,你没猜错,相信自己的英语水平. 先来一个简单的例子来看一下这个东西怎么用: 比如我们的数据库中有这样一 ...

  6. Yii2之类自动加载

    在yii中,程序中需要使用到的类无需事先加载其类文件,在使用的时候才自动定位类文件位置并加载之,这么高效的运行方式得益于yii的类自动加载机制. Yii的类自动加载实际上使用的是PHP的类自动加载,所 ...

  7. Excel 查找某列中的数据在另一列是否存在及输出第三例的数据

    最近在操作Excel文件数据导入数据库时,经常需要检查Excel中哪些数据数据库中已经存在,哪些不存在,然后再将不存在数据库中的Excel数据导入:在此过程中,经常需要操作Excel中的数据,所以.也 ...

  8. Android插件化-RePlugin项目集成与使用

    前言:前一段时间新开源了一种全面插件化的方案-- RePlugin,之前一种都在关注 DroidPlugin 并且很早也在项目中试用了,但最终没有投入到真正的生产环节,一方面是项目中没有特别需要插件化 ...

  9. Jacobi symbol(裸雅可比符号)

    Jacobi symbol Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Tot ...

  10. centos 6.9安装zabbix 3.0

    Linux下常用的系统监控软件有Nagios.Cacti.Zabbix.Monit等,这些开源的软件,可以帮助我们更好的管理机器,在第一时间内发现,并警告系统维护人员. 今天开始研究下Zabbix,使 ...