python3 rabbitMQ学习与测试
安装命令
# elang
(base) adocir@adocir:~$ sudo apt-get install erlang-nox
# rabbitmq-server
(base) adocir@adocir:~$ sudo apt-get install -y rabbitmq-server
# 安装完成后会自动启动
#查看状态
(base) adocir@adocir:~$ systemctl status rabbitmq-server
#启用web控制台
(base) adocir@adocir:~$ sudo rabbitmq-plugins enable rabbitmq_management
访问web控制台
http://127.0.0.1:15672
默认账号密码: guest/guest
新增管理员用户并删除默认账号
receive
# !/usr/bin/env python
# coding=utf8
import pika
import json
# 回调函数
def callback(ch, method, properties, body):
print(f"Got message: {body}")
credentials = pika.PlainCredentials('guest', 'guest') # 登录账号密码设置
connection = pika.BlockingConnection(
pika.ConnectionParameters(host='localhost', credentials=credentials))
channel = connection.channel()
print(channel)
channel.queue_declare(queue='adocir') # 队列初始化定义
channel.basic_consume(queue="adocir", on_message_callback=callback, auto_ack=True)
print("[*] Waiting for messages. To exit press CTRL+C'")
channel.start_consuming() # 开启监听,阻塞
send
# !/usr/bin/env python
# coding=utf8
import pika
import json
dic = {'type':'test', 'command':'test', 'uuid':'', 'status':'OK', 'error_message':False, 'results':'test_results'}
dic = json.dumps(dic)
credentials = pika.PlainCredentials('guest', 'guest') # 登录账号密码设置
connection = pika.BlockingConnection(
pika.ConnectionParameters(host='localhost', credentials=credentials))
channel = connection.channel()
# channel.exchange_declare(exchange='default-topic-exchange', exchange_type='topic', durable=True) # 交换机,本地不需要
# channel.basic_qos(prefetch_count=1)
channel.basic_publish(exchange='', routing_key='adocir', body=dic)
python下rabbitMQ的一些重连方式
借鉴自python使用pika操作rabbitmq总结(一)
while实现
import pika
while True:
try:
connection = pika.BlockingConnection()
channel = connection.channel()
channel.basic_consume('adocir', on_message_callback)
channel.start_consuming()
# Don't recover if connection was closed by broker
except pika.exceptions.ConnectionClosedByBroker:
break
# Don't recover on channel errors
except pika.exceptions.AMQPChannelError:
break
# Recover on all other connection errors
except pika.exceptions.AMQPConnectionError:
continue
retry实现
@retry(pika.exceptions.AMQPConnectionError, delay=5, jitter=(1, 3))
def rabbitmq_receiver():
credentials = pika.PlainCredentials(cfg.RABBITMQ_USERNAME, cfg.RABBITMQ_PASSWORD)
connection = pika.BlockingConnection(
pika.ConnectionParameters(
host=cfg.RABBITMQ_URL,
port=int(cfg.RABBITMQ_PORT),
credentials=credentials,
connection_attempts=int(cfg.MAX_CONNECT_ATTEMPTS),
retry_delay=int(cfg.MAX_RETRY_DELAY),
heartbeat=0))
channel = connection.channel()
channel.exchange_declare(exchange='default-topic-exchange', exchange_type='topic', durable=True)
# client.queue_declare(cfg.TASK_TOPIC)
channel.basic_consume(queue=cfg.TASK_TOPIC, on_message_callback=message_resolution, auto_ack=True)
try:
channel.start_consuming()
except pika.exceptions.ConnectionClosedByBroker:
pass
外网on_close_callback方法
pika/examples/asynchronous_consumer_example.py
后续补充更新
队列长度限制
# RabbitMQ有两种对队列长度的限制方式
# 对队列中消息的条数进行限制 x-max-length
# 对队列中消息的总量进行限制 x-max-length-bytes
# 设置队列最大长度(遵循FIFO先进先出规则)
# 设置adocir队列持久化,最大长度为2(消费者和生产者都需要对队列声明持久化)
channel.queue_declare(queue='adocir', durable=True, arguments={'x-max-length': 2})
消费失败时回退消息
消费者如果调用callback处理数据失败后,则消息会丢失。声明后可以在处理失败后将数据回退给队列。
# no_ack 设置成 False,在调用callback函数时,未收到确认标识,消息会重回队列。True,无论调用callback成功与否,消息都被消费掉
channel.basic_consume(callback,queue = 'adocir', no_ack = False)
消息存活时间
创建queue时设置该参数可指定消息在该queue中存活时间。
# 消息的存活时间是60秒,超时则丢弃
channel.queue_declare(queue='adocir', durable=True, arguments={'x-message-ttl': 60000})
死信队列
x-dead-letter-routing-key
x-dead-letter-exchange
创建queue时参数arguments设置了x-dead-letter-routing-key和x-dead-letter-exchange,会在x-message-ttl时间到期后把消息放到x-dead-letter-routing-key和x-dead-letter-exchange指定的队列中达到延迟队列的目的。
arguments = {
'x-message-ttl': 10000, # 延迟时间 (毫秒)
'x-dead-letter-exchange': exchange, # 延迟结束后指向交换机(死信收容交换机)
'x-dead-letter-routing-key': queue, # 延迟结束后指向队列(死信收容队列),可直接设置queue name也可以设置routing-key
}
channel.queue_declare(
queue='adocir',
durable=True,
arguments=arguments
)
队列存活时间
创建queue时参数arguments设置了x-expires参数,会在x-expires到期后直接删除queue本身。
channel.queue_declare(
queue='adocir',
durable=True,
arguments={'x-expires': 6000} # 队列的存活时间是6秒
)
消息优先级
rabbitMQ官网文档
版本限制3.5+
创建queue时arguments可以使用x-max-priority参数声明优先级队列 。该参数应该是一个整数,表示队列应该支持的最大优先级。
建议使用1到10之间。目前使用更多的优先级将消耗更多的资源(Erlang进程)。
设置该参数同时设置死信队列时或造成已过期的低优先级消息会在未过期的高优先级消息后面执行。
该参数会造成额外的CPU消耗。
channel.queue_declare(
queue='adocir',
durable=True,
arguments={'x-max-priority': 10} # 队列最大优先级为10
)
参考
rabbitMQ官网
rabbitmq-tutorials-java
rabbitmq-tutorials-python
Topic python参考
rabbitmq queue_declare arguments参数注释