RabbitMQ常用方法介绍python
来源:互联网 发布:淘宝客佣金生效时间 编辑:程序博客网 时间:2024/06/08 02:16
介绍:
RabbitMQ是一个消息代理 - 一个消息系统的媒介。它可以为你的应用提供一个通用的消息发送和接收平台,并且保证消息在传输过程中的安全。详细介绍RabbitMQ优点,特点,请见中文文档点这里Chinese Document。
交换机和交换机类型
Name(交换机类型) Default pre-declared names(预声明的默认名称)
Direct exchange(直连交换机) (Empty string) and amq.direct
Fanout exchange(扇型交换机) amq.fanout
Topic exchange(主题交换机) amq.topic
Headers exchange(头交换机) amq.match (and amq.headers in RabbitMQ)
CentoOS安装RabbitMQ的server服务
安装配置epel源 $ rpm -ivh http://dl.fedoraproject.org/pub/epel/6/i386/epel-release-6-8.noarch.rpm安装erlang $ yum -y install erlang安装RabbitMQ $ yum -y install rabbitmq-server
MacOS
brew install rabbitmq
安装python客户端
pip install pika
1.Hello world
#!/usr/bin/env pythonimport pika# ######################### 生产者 #########################connection = pika.BlockingConnection(pika.ConnectionParameters( host='localhost'))channel = connection.channel()'''现在我们已经连接上服务器了,那么,在发送消息之前我们需要确认队列是存在的。如果我们把消息发送到一个不存在的队列,RabbitMQ会丢弃这条消息。我门先创建一个名为hello的队列,然后把消息发送到这个队列中。'''channel.queue_declare(queue='hello') '''在RabbitMQ中,消息是不能直接发送到队列,它需要发送到交换机(exchange)中,它使用一个空字符串来标识。交换机允许我们指定某条消息需要投递到哪个队列,routing_key参数必须指定为队列的名称'''channel.basic_publish(exchange='', routing_key='hello', body='Hello World!')print(" [x] Sent 'Hello World!'")'''在退出程序之前,我们需要确认网络缓冲已经被刷写、消息已经投递到RabbitMQ。完成这些事情(正确的关闭连接)是很简单的'''connection.close()
#!/usr/bin/env pythonimport pika# ########################## 消费者 ##########################connection = pika.BlockingConnection(pika.ConnectionParameters( host='localhost'))channel = connection.channel()channel.queue_declare(queue='hello')def callback(ch, method, properties, body): print(" [x] Received %r" % body)channel.basic_consume(callback, queue='hello', no_ack=True)print(' [*] Waiting for messages. To exit press CTRL+C')channel.start_consuming()
- acknowledgment
no-ack = False,如果消费者遇到情况(its channel is closed, connection is closed, or TCP connection is lost)挂掉了,那么,RabbitMQ会重新将该任务添加到队列中。只需设置channel如下即可:
channel.basic_consume(callback, queue='hello', no_ack=False)
现在就可以在终端中运行我们的程序了。首先,用send.py重续发送一条消息:
$ python send.py[x] Sent 'Hello World!'
生产者(producer)程序send.py每次运行之后就会停止。现在我们就来接收消息:
$ python receive.py[*] Waiting for messages. To exit press CTRL+C[x] Received 'Hello World!'
成功了!我们已经通过RabbitMQ发送第一条消息。你也许已经注意到了,receive.py程序并没有退出。它一直在准备获取消息,你可以通过Ctrl-C来中止它。
2.消息持久化 durable
如果你没有特意告诉RabbitMQ,那么在它退出或者崩溃的时候,将会丢失所有队列和消息。为了确保信息不会丢失,有两个事情是需要注意的:我们必须把“队列”和“消息”设为持久化。
首先,为了不让队列消失,需要把队列声明为持久化(durable):
channel.queue_declare(queue='hello', durable=True)
尽管这行代码本身是正确的,但是仍然不会正确运行。因为我们已经定义过一个叫hello的非持久化队列。RabbitMq不允许你使用不同的参数重新定义一个队列,它会返回一个错误。但我们现在使用一个快捷的解决方法——用不同的名字,例如task_queue。
这个queue_declare必须在生产者(producer)和消费者(consumer)对应的代码中修改。
这时候,我们就可以确保在RabbitMq重启之后queue_declare队列不会丢失。另外,我们需要把我们的消息也要设为持久化——将delivery_mode的属性设为2。
channel.basic_publish(exchange='', routing_key="task_queue", body=message, properties=pika.BasicProperties( delivery_mode = 2, # make message persistent ))
3.发布订阅
发布订阅和简单的消息队列区别在于,发布订阅会将消息发送给所有的订阅者,而消息队列中的数据被消费一次便消失。所以,RabbitMQ实现发布和订阅时,会为每一个订阅者创建一个队列,而发布者发布消息时,会将消息放置在所有相关队列中。
exchange type = fanout
#!/usr/bin/env pythonimport pikaimport sysconnection = 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()
#!/usr/bin/env pythonimport pikaconnection = 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.queuechannel.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()
4.关键字发送
exchange type = direct
之前事例,发送消息时明确指定某个队列并向其中发送消息,RabbitMQ还支持根据关键字发送,即:队列绑定关键字,发送者将数据根据关键字发送到消息exchange,exchange根据 关键字 判定应该将数据发送至指定队列。
#!/usr/bin/env pythonimport pikaimport sysconnection = pika.BlockingConnection(pika.ConnectionParameters( host='localhost'))channel = connection.channel()channel.exchange_declare(exchange='direct_logs', type='direct')result = channel.queue_declare(exclusive=True)queue_name = result.method.queueseverities = sys.argv[1:]if not severities: sys.stderr.write("Usage: %s [info] [warning] [error]\n" % sys.argv[0]) sys.exit(1)for severity in severities: channel.queue_bind(exchange='direct_logs', queue=queue_name, routing_key=severity)print(' [*] Waiting for logs. To exit press CTRL+C')def callback(ch, method, properties, body): print(" [x] %r:%r" % (method.routing_key, body))channel.basic_consume(callback, queue=queue_name, no_ack=True)channel.start_consuming()
#!/usr/bin/env pythonimport pikaimport sysconnection = pika.BlockingConnection(pika.ConnectionParameters( host='localhost'))channel = connection.channel()channel.exchange_declare(exchange='direct_logs', type='direct')severity = sys.argv[1] if len(sys.argv) > 1 else 'info'message = ' '.join(sys.argv[2:]) or 'Hello World!'channel.basic_publish(exchange='direct_logs', routing_key=severity, body=message)print(" [x] Sent %r:%r" % (severity, message))connection.close()
6.模糊匹配
exchange type = topic
在topic类型下,可以让队列绑定几个模糊的关键字,之后发送者将数据发送到exchange,exchange将传入”路由值“和 ”关键字“进行匹配,匹配成功,则将数据发送到指定队列。
# 表示可以匹配 0 个 或 多个 单词* 表示只能匹配 一个 单词
#!/usr/bin/env pythonimport pikaimport sysconnection = pika.BlockingConnection(pika.ConnectionParameters( host='localhost'))channel = connection.channel()channel.exchange_declare(exchange='topic_logs', type='topic')result = channel.queue_declare(exclusive=True)queue_name = result.method.queuebinding_keys = sys.argv[1:]if not binding_keys: sys.stderr.write("Usage: %s [binding_key]...\n" % sys.argv[0]) sys.exit(1)for binding_key in binding_keys: channel.queue_bind(exchange='topic_logs', queue=queue_name, routing_key=binding_key)print(' [*] Waiting for logs. To exit press CTRL+C')def callback(ch, method, properties, body): print(" [x] %r:%r" % (method.routing_key, body))channel.basic_consume(callback, queue=queue_name, no_ack=True)channel.start_consuming()
#!/usr/bin/env pythonimport pikaimport sysconnection = pika.BlockingConnection(pika.ConnectionParameters( host='localhost'))channel = connection.channel()channel.exchange_declare(exchange='topic_logs', type='topic')routing_key = sys.argv[1] if len(sys.argv) > 1 else 'anonymous.info'message = ' '.join(sys.argv[2:]) or 'Hello World!'channel.basic_publish(exchange='topic_logs', routing_key=routing_key, body=message)print(" [x] Sent %r:%r" % (routing_key, message))connection.close()
- RabbitMQ常用方法介绍python
- python的functools模块常用方法介绍
- python(十一)上:RabbitMQ 使用详细介绍
- python(十一)上:RabbitMQ 使用详细介绍
- rabbitmq channel接口常用方法详解
- Python的os模块常用属性及方法介绍
- 介绍Python中几个常用的类方法
- python常用模块介绍
- python 常用模块介绍
- Python常用模块介绍
- Python 常用功能模块介绍
- Python常用模块介绍
- python常用模块介绍
- Python 常用模块介绍
- python 常用模块介绍
- RabbitMq介绍
- RabbitMQ介绍
- RabbitMQ介绍
- opentsdb遇到的坑和优化建议
- 持续集成的注意点
- JFinal在使用oracle数据库时页面显示EL表达式获取不到值
- 深度学习中防止过拟合的方法
- JS中的event 对象详解
- RabbitMQ常用方法介绍python
- OkHttp面试之--HttpEngine中的readResponse流程简介
- Intent详解
- JS错误:Uncaught SyntaxError: Unexpected token ILLEGAL
- 计算机视觉基础4——对极几何(Epipolar Geometry)
- 训练总结 By_Cqy
- 数据库查询实验60习题答案
- Express---jade模板引擎(二)
- Tomcat下访问项目不需要输入项目名称的配置方法