使用python连接rabbitmq

使用python连接rabbitmq的时候,需要第三方库 pika

pika 的安装

......@ubunut: ~$ sudo pip3 install pika

此处,创建两个py文件

  • send.py
#!/usr/bin/python3
# send.py

import pika

# 创建连接
con = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = con.channel()
# 声明消息队列 队列名称为‘hello’
channel.queue_declare(queue='hello')
# 消息的生产者,exchange指定交换器, routing_key指定消息队列, body要发送的消息
channel.basic_publish(exchange='', routing_key='hello', body='Hello World')

print(" [x] sent 'Hello World'")
# 关闭连接
con.close()
  • receive.py
#!/usr/bin/python3
# receive.py

import pika

con = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = con.channel()

# 多次使用queue_declare创建消息队列的时候,如果消息队列已经存在,则不创建新的
channel.queue_declare(queue='hello')

print("[*] Wating for messages To exit press Ctrl+C")


def callback(ch, method, properties, body):
    print('[x] Received {}'.format(body))
# 参数一: 消息队列的名称
# 参数二: 消息处理的回调函数
channel.basic_consume('hello', callback, auto_ack = True)
# 开始消费
channel.start_consuming()

如何保证消息队列消息不丢失

  • 如果消费者在处理的时候出现异常,我们希望消息会自动转发给其他消费者,在rabbitmq中有效确认机制,auto_ack参数(最近版本的pika,以前的版本是no_ack),默认是False。表示消息需要确认,这样其中有消费者当机了,那就可以把这个消息,转发给其他消费者.
    消费者收到消息,正常处理后,此时才通知队列可以将消息从队列里面删除;如果消费者挂掉,与server的链接通道会关闭或者tcp连接丢失,这时候server知道了这个情况,就会自动重发消息
#!/usr/bin/python3
# receive.py

import pika

con = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = con.channel()

# 多次使用queue_declare创建消息队列的时候,如果消息队列已经存在,则不创建新的
channel.queue_declare(queue='hello')

print("[*] Wating for messages To exit press Ctrl+C")


def callback(ch, method, properties, body):
    print('[x] Received {}'.format(body))
# 参数一: 消息队列的名称
# 参数二: 消息处理的回调函数
channel.basic_consume('hello', callback)
# 开始消费
channel.start_consuming()
  • 防止Server挂掉了: 1、将队列保存;2、将消息持久化

在声明队列的时候,durable = True,这样Server挂掉,队列还在

# 要保证生产者和消费者生命的队列一样,都为True或者同时为False。durable(耐用)
channel.queue_declare(queue=‘hello‘,durable=True)   

在声明交换机的时候,将消息进行持久化:delivery_mode = 2 (发送模式),这样Server挂掉,消息还在
properties(属性)

channel.basic_publish(exchange=‘‘,routing_key=‘hello‘,body=‘Hello World!‘,properties=pika.BasicProperties(delivery_mode=2,))

exchange 交换机的选择

  • fanout 这种模式下,传递到 exchange 的消息将会转发到所有与其绑定的 queue 上
  • direct 这种工作模式的原理是 消息发送至 exchange,exchange 根据 路由键(routing_key)转发到相对应的 queue 上
  • topic 前面提到的direct规则是严格意义上的匹配,换言之Routing Key必须与Binding Key相匹配的时候才将消息传送给Queue,那么topic这个规则就是模糊匹配,可以通过通配符满足一部分规则就可以传送

fanout 模式

  • 不需要指定 routing_key ,即使指定了也是无效。
  • 需要提前将 exchange 和 queue 绑定,一个 exchange 可以绑定多个 queue,一个queue可以绑定多个exchange。
  • 需要先启动 订阅者,此模式下的队列是 consumer 随机生成的,发布者 仅仅发布消息到 exchange ,由 exchange 转发消息至 queue。
#!/usr/bin/python3
# send.py

import pika
import json
con = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = con.channel()
# 声明exchange,由exchange指定消息在哪个队列传递,如不存在,则创建。durable = True 代表exchange持久化存储,False 非持久化存储
channel.exchange_declare(exchange='python-test', durable=True, exchange_type='fanout')

for i in range(20):
    message = json.dumps({'OrdersId': '1000{}'.format(i)})
    # 向队列插入数值 routing_key是队列名。delivery_mode = 2 声明消息在队列中持久化,delivery_mod = 1 消息非持久化。routing_key 不需要配置
    channel.basic_publish(exchange='python-test', routing_key='', body=message, properties=pika.BasicProperties(delivery_mode = 2))
    print(message)
con.close()
#!/usr/bin/python3
# receive.py

import pika

con = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))

channel = con.channel()
# 创建临时队列,consumer关闭后,队列自动删除
result = channel.queue_declare(exclusive=True, queue='')

channel.exchange_declare(exchange='python-test', durable=True, exchange_type='fanout')
# 绑定exchange和队列  exchange 使我们能够确切地指定消息应该到哪个队列去
channel.queue_bind(exchange = 'python-test', queue=result.method.queue)

print("[*] Wating for messages To exit press Ctrl+C")

def callback(ch, method, properties, body):
    ch.basic_ack(delivery_tag = method.delivery_tag)
    print(body.decode())
# 设置成 False,在调用callback函数时,未收到确认标识,消息会重回队列。True,无论调用callback成功与否,消息都被消费掉
channel.basic_consume(result.method.queue, callback, auto_ack=False)
channel.start_consuming()

direct 模式

  • 可以使用默认 exchange =’ ’ ,也可以自定义 exchange
  • 这种模式下不需要将 exchange 和 任何进行绑定,当然绑定也是可以的。可以将 exchange 和 queue ,routing_key 和 queue 进行绑定
  • 传递或接受消息时 需要 指定 routing_key
  • 需要先启动 订阅者,此模式下的队列是 consumer 随机生成的,发布者 仅仅发布消息到 exchange ,由 exchange 转发消息至 queue。
#!/usr/bin/python3
# send.py

import pika
import json

con = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = con.channel()
channel.exchange_declare(exchange='python-test-2', durable=True, exchange_type='direct')
for i in range(20):
    message = json.dumps({'OrdersId': '1000{}'.format(i)})
    # 指定 routing_key。delivery_mode = 2 声明消息在队列中持久化,delivery_mod = 1 消息非持久化
    channel.basic_publish(exchange='python-test-2', routing_key='OrderId', body=message)
    print(message)
con.close()
#!/usr/bin/python3
# receive.py

import pika
con = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = con.channel()

result = channel.queue_declare(exclusive=True, queue='')

channel.exchange_declare(exchange='python-test-2', durable=True, exchange_type='direct')
channel.queue_bind(exchange = 'python-test-2', queue=result.method.queue, routing_key='OrderId')

print("[*] Wating for messages To exit press Ctrl+C")
def callback(ch, method, properties, body):
    ch.basic_ack(delivery_tag = method.delivery_tag)
    print(body.decode())
channel.basic_consume(result.method.queue, callback, auto_ack=False)
channel.start_consuming()

topic
python3 receive.py OrdersId OrderIds
python3 send.py

  • 这种模式和第二种模式差不多,exchange 也是通过 路由键 routing_key 来转发消息到指定的 queue 。 不同点是 routing_key 使用正则表达式支持模糊匹配,但匹配规则又与常规的正则表达式不同,比如‘’#‘’是匹配全部,“*”是匹配一个词。

  • 举例:routing_key =“#orderid#”,意思是将消息转发至所有 routing_key 包含 “orderid” 字符的队列中

# !/usr/bin/python3
# send.py
import pika
import json

con = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = con.channel()

channel.exchange_declare(exchange='python-test-3', durable=True, exchange_type='topic')
for i in range(20):
    message = json.dumps({'OrdersId': '1000{}'.format(i)})
    channel.basic_publish(exchange='python-test-3', routing_key='OrdersId', body=message)
    print(message)

con.close()
# !/usr/bin/python3
# receive.py

import pika
import sys

con = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))
channel = con.channel()

result = channel.queue_declare(exclusive=True, queue='')
channel.exchange_declare(exchange='python-test-3', durable=True, exchange_type='topic')
binding_keys = sys.argv[1:]
print('-->',binding_keys)
if not binding_keys:
    print('------>')
    sys.exit(1)
for i in binding_keys:
    channel.queue_bind(exchange = 'python-test-3', queue=result.method.queue, routing_key=i)
print("[*] Wating for messages To exit press Ctrl+C")
def callback(ch, method, properties, body):
    ch.basic_ack(delivery_tag = method.delivery_tag)
    print(body.decode())

channel.basic_consume(result.method.queue, callback, auto_ack=False)
channel.start_consuming()
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值