Python使用消息队列rabbitmq

项目文件:base.pypublish.pyconsumer.py

base.py

python 复制代码
import json
import datetime
import time
import random
import pika
from pika.exceptions import ChannelClosed, ConnectionClosed

# rabbitmq 配置信息
MQ_CONFIG = {
    "hostname": "127.0.0.1",
    "port": 5672,
    "vhost": "my_vhost",
    "username": "admin",
    "password": "adminxxx",
    "exchange": "my_exchange",
    "queue": "my_queue",
    "routing_key": "my_key"
}

class RabbitMQServer(object):
    def __init__(self):
        self.config = MQ_CONFIG  # 配置文件加载
        self.host = self.config.get("hostname")
        self.port = self.config.get("port")
        self.username = self.config.get("username")
        self.password = self.config.get("password")
        self.vhost = self.config.get("vhost")
        self.exchange = self.config.get("exchange")
        self.queue = self.config.get("queue")
        self.routing_key = self.config.get("routing_key")

        self.connection = None
        self.channel = None

        # 关于队列的声明,如果使用同一套参数进行声明了,就不能再使用其他参数来声明
        self.arguments = {
            'x-message-ttl': 82800000,   # 设置队列中的所有消息的生存周期
            'x-expires': 82800000,       # 当队列在指定的时间没有被访问(consume, basicGet, queueDeclare...)就会被删除
            'x-max-length': 100000,      # 限定队列的消息的最大条数,超过指定条数将会把最早的几条删除掉
            'x-max-priority': 10         # 声明队列时先定义最大优先级值,在发布消息的时候指定该消息的优先级
        }

    def reconnect(self):
        try:
            if self.connection and not self.connection.is_closed:
                self.connection.close()

            credentials = pika.PlainCredentials(self.username, self.password)
            parameters = pika.ConnectionParameters(self.host, self.port, self.vhost, credentials)

            self.connection = pika.BlockingConnection(parameters)
            self.channel = self.connection.channel()
            self.channel.exchange_declare(exchange=self.exchange, exchange_type="direct", durable=True)
            self.channel.queue_declare(queue=self.queue, exclusive=False, durable=True, arguments=self.arguments) 
            self.channel.queue_bind(exchange=self.exchange, queue=self.queue, routing_key=self.routing_key)

            if isinstance(self, RabbitComsumer):
                self.channel.basic_qos(prefetch_count=1)  # prefetch 表明最大阻塞未ack的消息数量
                self.channel.basic_consume(on_message_callback=self.consumer_callback, queue=self.queue, auto_ack=False)

        except Exception as e:
            print("RECONNECT: ", e)


class RabbitPublisher(RabbitMQServer):
    def __init__(self):
        super(RabbitPublisher, self).__init__()

    def start_publish(self):
        self.reconnect()
        i = 1
        while True:
            message = {"value": i}
            try:
                self.channel.basic_publish(exchange=self.exchange, routing_key=self.routing_key, body=json.dumps(message))
                print("Publish value: ", i)
                i += 1
                time.sleep(3)
            except ConnectionClosed as e:
                print("ConnectionClosed: ", e)
                self.reconnect()
                time.sleep(2)
            except ChannelClosed as e:
                print("ChannelClosed: ", e)
                self.reconnect()
                time.sleep(2)
            except Exception as e:
                print("basic_publish: ", e)
                self.reconnect()
                time.sleep(2)


class RabbitComsumer(RabbitMQServer):
    def __init__(self):
        super(RabbitComsumer, self).__init__()

    def execute(self, body):
        body = body.decode('utf8')
        body = json.loads(body)
        print(body["value"])
        return True

    def consumer_callback(self, channel, method, properties, body):
        result = self.execute(body)
        if channel.is_open:
            if result:
                channel.basic_ack(delivery_tag=method.delivery_tag)   # 发送ack
            else:
                channel.basic_nack(delivery_tag=method.delivery_tag, multiple=False, requeue=True)
        if not channel.is_open:
            print("Callback 接收频道关闭,无法ack")

    def start_consumer(self):
        self.reconnect()
        while True:
            try:
                self.channel.start_consuming()  #启动消息接受 进入死循环
            except ConnectionClosed as e:
                print("ConnectionClosed: ", e)
                self.reconnect()
                time.sleep(2)
            except ChannelClosed as e:
                print("ChannelClosed: ", e)
                self.reconnect()
                time.sleep(2)
            except Exception as e:
                print("consuming: ", e)
                self.reconnect()
                time.sleep(2)

publish.py

python 复制代码
from base import RabbitPublisher

if __name__ == '__main__':
    publisher = RabbitPublisher()
    publisher.start_publish()

consumer.py

python 复制代码
from base import RabbitComsumer

if __name__ == '__main__':
    consumer = RabbitComsumer()
    consumer.start_consumer()
相关推荐
ANYOLY1 小时前
RabbitMQ 核心知识点
分布式·rabbitmq
Learn Beyond Limits1 小时前
Regression vs. Classification|回归vs分类
人工智能·python·算法·ai·分类·数据挖掘·回归
hygge9991 小时前
JVM GC 垃圾回收体系完整讲解
java·开发语言·jvm·经验分享·面试
wuwu_q2 小时前
通俗易懂 + Android 开发实战的方式,详细讲讲 Kotlin 中的 StateFlow
android·开发语言·kotlin
峰哥的Android进阶之路2 小时前
Kotlin面试题总结
android·开发语言·kotlin
froginwe112 小时前
RSS 语法:全面解析与优化指南
开发语言
不去幼儿园2 小时前
【强化学习】可证明安全强化学习(Provably Safe RL)算法详细介绍
人工智能·python·算法·安全·机器学习·强化学习
重启编程之路2 小时前
python 基础学习socket -UDP编程
python·网络协议·学习·udp
小飞大王6662 小时前
JavaScript基础知识总结(六)模块化规范
开发语言·javascript·ecmascript