Python操作RabbitMQ服务器实现消息队列的路由功能


Posted in Python onJune 29, 2016

Python使用Pika库(安装:sudo pip install pika)可以操作RabbitMQ消息队列服务器(安装:sudo apt-get install rabbitmq-server),这里我们来看一下MQ相关的路由功能。

路由键的实现

比如有一个需要给所有接收端发送消息的场景,但是如果需要自由定制,有的消息发给其中一些接收端,有些消息发送给另外一些接收端,要怎么办呢?这种情况下就要用到路由键了。

路由键的工作原理:每个接收端的消息队列在绑定交换机的时候,可以设定相应的路由键。发送端通过交换机发送信息时,可以指明路由键 ,交换机会根据路由键把消息发送到相应的消息队列,这样接收端就能接收到消息了。

这边继上一篇,还是用send.py和receive.py来模拟实现路由键的功能。send.py表示发送端,receive.py表示接收端。实例的功能就是将info、warning、error三种级别的信息发送到不同的接收端。

send.py代码分析

#!/usr/bin/env python
#coding=utf8
import pika
 
connection = pika.BlockingConnection(pika.ConnectionParameters(
        'localhost'))
channel = connection.channel()
 
#定义交换机,设置类型为direct
channel.exchange_declare(exchange='messages', type='direct')
 
#定义三个路由键
routings = ['info', 'warning', 'error']
 
#将消息依次发送到交换机,并设置路由键
for routing in routings:
  message = '%s message.' % routing
  channel.basic_publish(exchange='messages',
             routing_key=routing,
             body=message)
  print message
 
connection.close()

receive.py代码分析

#!/usr/bin/env python
#coding=utf8
import pika, sys
 
connection = pika.BlockingConnection(pika.ConnectionParameters(
        'localhost'))
channel = connection.channel()
 
#定义交换机,设置类型为direct
channel.exchange_declare(exchange='messages', type='direct')
 
#从命令行获取路由键参数,如果没有,则设置为info
routings = sys.argv[1:]
if not routings:
  routings = ['info']
 
#生成临时队列,并绑定到交换机上,设置路由键
result = channel.queue_declare(exclusive=True)
queue_name = result.method.queue
for routing in routings:
  channel.queue_bind(exchange='messages',
            queue=queue_name,
            routing_key=routing)
 
def callback(ch, method, properties, body):
  print " [x] Received %r" % (body,)
 
channel.basic_consume(callback, queue=queue_name, no_ack=True)
 
print ' [*] Waiting for messages. To exit press CTRL+C'
channel.start_consuming()

打开两个终端,一个运行代码python receive.py info warning,表示只接收info和warning的消息。另外一个终端运行send.py,可以观察到接收终端只接收到了info和warning的消息。如果打开多个终端运行receive.py,并传入不同的路由键参数,可以看到更明显的效果。

当接收端正在运行时,可以使用rabbitmqctl list_bindings来查看绑定情况。

路由键模糊匹配
路由键模糊匹配,就是可以使用正则表达式,和常用的正则表示式不同,这里的话“#”表示所有、全部的意思;“*”只匹配到一个词。看完示例就能明白了。

这边继上面的例子,还是用send.py和receive.py来实现路由键模糊匹配的功能。send.py表示发送端,receive.py表示接收端。实例的功能大概是这样:比如你有个知心好朋友,不管开心、伤心、工作上的还是生活上的事情都可以和她说;还有一些朋友可以分享开心的事情;还有一些朋友,你可以把不开心的事情和她说。

send.py代码分析

因为要进行路由键模糊匹配,所以交换机的类型要设置为topic,设置为topic,就可以使用#,*的匹配符号了。

#!/usr/bin/env python
#coding=utf8
import pika
 
connection = pika.BlockingConnection(pika.ConnectionParameters(
        'localhost'))
channel = connection.channel()
 
#定义交换机,设置类型为topic
channel.exchange_declare(exchange='messages', type='topic')
 
#定义路由键
routings = ['happy.work', 'happy.life', 'sad.work', 'sad.life']
 
#将消息依次发送到交换机,并设定路由键
for routing in routings:
  message = '%s message.' % routing
  channel.basic_publish(exchange='messages',
             routing_key=routing,
             body=message)
  print message
 
connection.close()

上例中定义了四种类型的消息,容易理解,就不解释了,然后依次发送出去。

receive.py代码分析

同样,交换机的类型要设定为topic就可以了。从命令行接收参数的功能稍微调整了一下,就是没有参数时报错退出。

#!/usr/bin/env python
#coding=utf8
import pika, sys
 
connection = pika.BlockingConnection(pika.ConnectionParameters(
        'localhost'))
channel = connection.channel()
 
#定义交换机,设置类型为topic
channel.exchange_declare(exchange='messages', type='topic')
 
#从命令行获取路由参数,如果没有,则报错退出
routings = sys.argv[1:]
if not routings:
  print >> sys.stderr, "Usage: %s [routing_key]..." % (sys.argv[0],)
  exit()
 
#生成临时队列,并绑定到交换机上,设置路由键
result = channel.queue_declare(exclusive=True)
queue_name = result.method.queue
for routing in routings:
  channel.queue_bind(exchange='messages',
            queue=queue_name,
            routing_key=routing)
 
def callback(ch, method, properties, body):
  print " [x] Received %r" % (body,)
 
channel.basic_consume(callback, queue=queue_name, no_ack=True)
 
print ' [*] Waiting for messages. To exit press CTRL+C'
channel.start_consuming()

打开四个终端,一个运行如下,表示任何事情都可以和她说:

python receive.py "#"

另外一个终端 运行如下,表示可以和她分享开心的事:

python receive.py "happy.*"

第三个运行如下,表示工作上的事情可以和她分享:

python receive.py "*.work"

最后一个运行python send.py。结果不难想象出来,就不贴出来了。

Python 相关文章推荐
浅谈Python中的私有变量
Feb 28 Python
解决Django数据库makemigrations有变化但是migrate时未变动问题
May 30 Python
对python 通过ssh访问数据库的实例详解
Feb 19 Python
基于python生成器封装的协程类
Mar 20 Python
Python通过cv2读取多个USB摄像头
Aug 28 Python
使用 Python ssh 远程登陆服务器的最佳方案
Mar 06 Python
使用Django实现把两个模型类的数据聚合在一起
Mar 28 Python
Python列表去重复项的N种方法(实例代码)
May 12 Python
如何解决安装python3.6.1失败
Jul 01 Python
详解pycharm2020.1.1专业版安装指南(推荐)
Aug 07 Python
Python实现钉钉/企业微信自动打卡的示例代码
Feb 02 Python
浅析Python中的套接字编程
Jun 22 Python
Python通过RabbitMQ服务器实现交换机功能的实例教程
Jun 29 #Python
Python+Pika+RabbitMQ环境部署及实现工作队列的实例教程
Jun 29 #Python
Python的消息队列包SnakeMQ使用初探
Jun 29 #Python
Python中线程的MQ消息队列实现以及消息队列的优点解析
Jun 29 #Python
深入理解Python中装饰器的用法
Jun 28 #Python
Python中的迭代器与生成器高级用法解析
Jun 28 #Python
Python设计足球联赛赛程表程序的思路与简单实现示例
Jun 28 #Python
You might like
虫族 Zerg 历史背景
2020/03/14 星际争霸
PHP4和PHP5性能测试和对比 测试代码与环境
2007/08/17 PHP
用PHP的超级变量$_POST获取HTML表单(HTML Form) 数据
2011/05/07 PHP
PHP pathinfo()获得文件的路径、名称等信息说明
2011/09/13 PHP
PHP大小写问题:函数名和类名不区分,变量名区分
2013/06/17 PHP
php常用字符串比较函数实例汇总
2014/11/24 PHP
Laravel 微信小程序后端实现用户登录的示例代码
2019/11/26 PHP
js查找父节点的简单方法
2008/06/28 Javascript
Jquery Uploadify多文件上传带进度条且传递自己的参数
2013/08/28 Javascript
javascript适合移动端的日期时间拾取器
2015/11/10 Javascript
javascript截图 jQuery插件imgAreaSelect使用详解
2016/05/04 Javascript
jQuery动态加载css文件实现方法
2016/06/15 Javascript
javascript入门之数组[新手必看]
2016/11/21 Javascript
jq stop()和:is(:animated)的用法及区别(详解)
2017/02/12 Javascript
Vue.js仿Metronic高级表格(一)静态设计
2017/04/17 Javascript
妙用Angularjs实现表格按指定列排序
2017/06/23 Javascript
js指定步长实现单方向匀速运动
2017/07/17 Javascript
基于vue实现网站前台的权限管理(前后端分离实践)
2018/01/13 Javascript
JS简单获取并修改input文本框内容的方法示例
2018/04/08 Javascript
vue后台管理之动态加载路由的方法
2018/08/13 Javascript
vue+elementUI实现表单和图片上传及验证功能示例
2019/05/14 Javascript
vue的滚动条插件实现代码
2019/09/07 Javascript
js通过循环多张图片实现动画效果
2019/12/19 Javascript
JavaScript 禁止用户保存图片的实现代码
2020/04/28 Javascript
python判断设备是否联网的方法
2018/06/29 Python
对Python3+gdal 读取tiff格式数据的实例讲解
2018/12/04 Python
python内存动态分配过程详解
2019/07/15 Python
python 实现批量替换文本中的某部分内容
2019/12/13 Python
Python实现在线批量美颜功能过程解析
2020/06/10 Python
Python3爬虫里关于Splash负载均衡配置详解
2020/07/10 Python
Html5原生拖拽相关事件简介以及基础实现
2020/11/19 HTML / CSS
MVC的各个部分都有那些技术来实现?如何实现?
2016/04/21 面试题
公司廉洁自律承诺书
2014/03/27 职场文书
小平您好观后感
2015/06/09 职场文书
HTML页面点击按钮关闭页面的多种方式
2022/12/24 HTML / CSS
使用CSS实现百叶窗效果示例代码
2023/05/07 HTML / CSS