- AMQP aio_pika 工具类sdk
import asyncio
import aio_pika
import logging
import json
class RabbitMQConnector:
def __init__(
self,
rabbitmq_ip,
rabbitmq_port,
ttl=21600000,
username="guest",
password="guest",
exchange_name="eason_exchange",
exchange_type="topic",
queue_name="example_queue",
routing_key=["eason_routing"],
heartbeat=60,
):
self.rabbitmq_ip = rabbitmq_ip
self.rabbitmq_port = rabbitmq_port
self.ttl = ttl
self.username = username
self.password = password
self.exchange_name = exchange_name
self.exchange_type = exchange_type
self.queue_name = queue_name
self.routing_key = routing_key
self.heartbeat = heartbeat
self.receive_message_queue = asyncio.Queue()
self.connection = None
self.channel = None
self.exchange = None
self.queue = None
self.consumer_task = None
async def on_connection_blocked(self):
logging.warning("Connection to RabbitMQ was blocked")
async def on_connection_unblocked(self):
logging.info("Connection to RabbitMQ was unblocked")
# 创建连接
async def connect(self):
while not self.channel:
try:
# 创建Connection
self.connection = await aio_pika.connect_robust(
f"amqp://{self.username}:{self.password}@{self.rabbitmq_ip}:{self.rabbitmq_port}/",
heartbeat=self.heartbeat,
blocked_connection_callback=self.on_connection_blocked,
unblocked_connection_callback=self.on_connection_unblocked,
)
# 创建 Channel
self.channel = await self.connection.channel()
# 声明交换机
self.exchange = await self.channel.declare_exchange(
self.exchange_name, self.exchange_type, durable=True
)
# 声明队列
args = {"x-message-ttl": self.ttl} if self.ttl else None
self.queue = await self.channel.declare_queue(
self.queue_name,
durable=True,
arguments=args,
)
# 绑定队列到交换机
for key in self.routing_key:
await self.queue.bind(self.exchange, key)
msg = "Connected to RabbitMQ Successed..."
print(msg)
logging.info(msg)
except Exception as ex:
logging.error(f"Failed to connect to RabbitMQ: {ex}")
await asyncio.sleep(5)
# 生产消息
async def publish(self, message: list):
try:
# Ensure the connection and channel are open
if self.connection is None or self.connection.is_closed:
await self.connect()
# Publish message
for key in self.routing_key:
await self.exchange.publish(
aio_pika.Message(
body=json.dumps(message).encode("utf-8"),
content_type="application/json",
),
routing_key=key,
)
logging.info(
f"Sent message to {self.exchange_name} routing_key: {self.routing_key}"
)
except Exception as ex:
logging.error(f"Failed to send message: {ex}")
# 回调函数,具体处理消息
async def callback(self, message: aio_pika.IncomingMessage):
try:
async with message.process(ignore_processed=True):
msg_body = message.body.decode() # 假设消息是二进制格式
msg = json.loads(msg_body)
routing_key = self.routing_key
await self.receive_message_queue.put((routing_key, msg))
await message.ack() # 手动确认消息(no_ack=False 时需要)
except Exception as ex:
logging.error(f"Error processing message: {ex}")
await message.nack() # 拒绝消息(可选)
# 消费信息
async def consume(self):
try:
if self.connection is None or self.connection.is_closed:
await self.connect()
if self.queue is None:
self.queue = await self.connection.channel.declare_queue(
self.queue_name
)
if self.consumer_task is None or self.consumer_task.done():
self.consumer_task = asyncio.create_task(
self.queue.consume(self.callback, no_ack=False)
)
logging.info("Consuming task started...")
# 等待消费者任务完成(通常不会完成,除非有错误或取消)
await self.consumer_task
except Exception as ex:
logging.error(ex)
await asyncio.sleep(5)
-
AMQP aio_pika 生产消息Demo
import asyncio
import logging
from async_amqp_sdk import RabbitMQConnector
async def publish_task(message: dict):
try:
rabbitmq_ip = "10.146.212.85"
rabbitmq_port = 30025
exchange_name = "eason_exchange"
queue_name = "eason_queue"
routing_key = ["eason_routing01", "eason_routing02"]
rabbitmq = RabbitMQConnector(
rabbitmq_ip=rabbitmq_ip,
rabbitmq_port=rabbitmq_port,
exchange_name=exchange_name,
queue_name=queue_name,
routing_key=routing_key,
)
while True:
await rabbitmq.publish(message)
print(f"publish message: {message}")
except Exception as ex:
msg = f"main function error:{ex}"
logging.error(msg)
async def main():
try:
# 并行运行两个任务
await asyncio.gather(
publish_task(
{
"message": "this is a test message aio_pika111111111111111111111111111111111"
}
),
publish_task(
{
"message": "this is a test message aio_pika222222222222222222222222222222222"
},
),
)
except Exception as ex:
msg = f"main function error:{ex}"
print(msg)
logging(msg)
if __name__ == "__main__":
asyncio.run(main())
- AMQP aio_pika 消费消息Demo
import asyncio
import logging
from async_amqp_sdk import RabbitMQConnector
async def process_messages(rabbitmq):
"""
持续处理来自队列的消息。
"""
while True:
try:
# 获取消息
message = await rabbitmq.receive_message_queue.get()
print(f"Consumed message: {message}")
except asyncio.CancelledError:
print("Message processing stopped by user")
break
except Exception as ex:
print(f"Error processing message: {ex}")
logging.error(f"Error processing message: {ex}", exc_info=True)
async def consume_task():
try:
rabbitmq_ip = "10.146.212.85"
rabbitmq_port = 30025
exchange_name = "eason_exchange"
queue_name = "eason_queue"
routing_key = ["eason_routing01", "eason_routing02"]
rabbitmq = RabbitMQConnector(
rabbitmq_ip=rabbitmq_ip,
rabbitmq_port=rabbitmq_port,
exchange_name=exchange_name,
queue_name=queue_name,
routing_key=routing_key,
)
# 启动消费者任务
consumer_task = asyncio.create_task(rabbitmq.consume())
# 启动消息处理任务
process_task = asyncio.create_task(process_messages(rabbitmq))
# 等待任务完成(通常不会完成,除非有错误或取消)
await asyncio.gather(consumer_task, process_task)
except Exception as ex:
msg = f"main function error:{ex}"
logging.error(msg)
async def main():
try:
await consume_task() # 消费消息
except Exception as ex:
msg = f"main function error:{ex}"
logging(msg)
if __name__ == "__main__":
asyncio.run(main())