RabbitMQ

来源:互联网 发布:网络测线器 编辑:程序博客网 时间:2024/06/08 16:04

RabbitMQ是开源消息队列服务器,实现了AMQP协议。提供了集群等特性。
官方文档:
https://www.rabbitmq.com/getstarted.html
RabbitMQ包含四个主要部分:
Publisher消息发布者
Exchange交换机 将消息发给队列
Queue队列
Consumer消息接受者
python 客户端pika安装:

pip install pika

例子

1.一对一简单实现:

send.py:

#!/usr/bin/python#-*- coding: utf-8 -*-import pika#If we wanted to connect to a broker on a different machine we'd simply specify its name or IP address here.connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))#创建连接channel = connection.channel()#create a company queue to which the message will be delivered:channel.queue_declare(queue='company')channel.basic_publish(exchange='',#交换机种类                      routing_key='company',                      body='holiday news')print('holiday news')connection.close()

receive.py:

#!/usr/bin/python#-*- coding: utf-8 -*-import pikaconnection = pika.BlockingConnection(pika.ConnectionParameters(               'localhost'))channel = connection.channel()#申明队列,没有就创建channel.queue_declare(queue='company')def callback(ch, method, properties, body):    print(" [x] Received %r" % body)#订阅队列channel.basic_consume(callback,                      queue='company',                      no_ack=True)print(' [*] Waiting for messages. To exit press CTRL+C')channel.start_consuming()

先启动消费者也就是接受者再启动生产者也就是发送者

消息持久化:
消息持久化 性能会降低
1.队列持久

channel.queue_declare(queue='company', durable=True)

2.消息持久:

channel.basic_publish(exchange='',                      routing_key="company",                      body='holiday news',                      properties=pika.BasicProperties(                         delivery_mode = 2, # make message persistent                      ))

消息公平分发:
各个消费者端,配置perfetch=1

channel.basic_qos(prefetch_count=1)

Publish/Subscribe 发布订阅模式

首先介绍Exchange几种类型
1. fanout:bind到对应交换路由的所有queue,用来处理广播路由。
比如一个消息对应到多个队列,同时处理不同业务逻辑。也可以随时改变绑定关系实现解耦,方便灵活。
2. direct:通过路由键routingKey发送给对应queue,用来处理单播路由。
3. topic:匹配路由键routingKey(表达式等方式)的queue,用来处理多播。

fanout例子


publisher.py:

#!/usr/bin/python#-*- coding: utf-8 -*-import 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()

subscriber.py:

#!/usr/bin/python#-*- coding: utf-8 -*-import pikaconnection = pika.BlockingConnection(pika.ConnectionParameters(    host='localhost'))channel = connection.channel()channel.exchange_declare(exchange='logs',                         type='fanout')# 不指定queue名字,rabbit会随机分配一个名字,exclusive=True会在使用此queue的消费者断开后,自动将queue删除result = channel.queue_declare(exclusive=True)queue_name = result.method.queue#绑定logs交换机,不同订阅者可以同时绑定这个交换机来获取消息,而不用管路由键routingKeychannel.queue_bind(exchange='logs',                   queue=queue_name)print(' [*] Waiting for logs. To exit press CTRL+C')#处理函数def callback(ch, method, properties, body):    print(" [1] %r" % body)channel.basic_consume(callback,                      queue=queue_name,                      no_ack=True)channel.start_consuming()

direct/topic

publisher.py:

#!/usr/bin/python#-*- coding: utf-8 -*-import 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()

subscriber.py:

#!/usr/bin/python#-*- coding: utf-8 -*-import 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)#订阅者根据routing_key来对应队列#例子 发布者,指定一个 routing_key 订阅者根据这个routing_key来对应一个队列 一对一#topic 则有一些规矩像正则一样 订阅者匹配到routing_key 来对应队列官网有更加详细说明和图例:#https://www.rabbitmq.com/tutorials/tutorial-five-python.htmlfor 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()
0 0
原创粉丝点击