博客
关于我
python rabbitmq实现简单/持久/广播/组播/topic/rpc消息异步发送可配置Django
阅读量:801 次
发布时间:2023-03-06

本文共 9073 字,大约阅读时间需要 30 分钟。

RabbitMQ在Windows环境下的安装与使用指南

1. 环境搭建

安装完成后,确保以下软件版本匹配:

  • Python 3.10.16
  • pip 24.2
  • Django 4.2
  • pika 1.3.2
  • celery 5.4.0
  • 其他依赖项如amqp 5.3.1、asgiref 3.8.1等保持一致

2. 创建Django项目

运行以下命令启动项目:

django-admin startproject django_rabbitmq

3. RabbitMQ配置

在Django项目的settings.py中添加以下配置:

BROKER_URL = 'amqp://guest:guest@localhost:15672/'CELERY_RESULT_BACKEND = 'rpc://'

4. RabbitMQ消息队列模式

4.1 简单模式

4.1.1 消息消费者(consumer.py)

import pikadef callback(ch, method, properties, body):    print(f"[x] Received {body.decode()}")def start_consuming():    connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))    channel = connection.channel()    channel.queue_declare(queue='hello')    channel.basic_consume(queue='hello', on_message_callback=callback, auto_ack=True)    print(' [*] Waiting for messages. To exit press CTRL+C')    channel.start_consuming()if __name__ == "__main__":    start_consuming()

4.1.2 消息生产者(producer.py)

import pikadef publish_message():    connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))    channel = connection.channel()    channel.queue_declare(queue='hello')    message = "Hello World!"    channel.basic_publish(exchange='', routing_key='hello', body=message)    print(f"[x] Sent '{message}'")    connection.close()if __name__ == "__main__":    publish_message()

运行命令:

python consumer.pypython producer.py

4.2 消息持久化模式

4.2.1 安全消费者(recv_msg_safe.py)

import timeimport pikadef callback(ch, method, properties, body):    print(" [x] Received %r" % body)    time.sleep(20)    print(" [x] Done")    ch.basic_ack(delivery_tag=method.delivery_tag)def start_consuming():    connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))    channel = connection.channel()    channel.queue_declare(queue='hello2', durable=True)    channel.basic_consume(queue='hello2', on_message_callback=callback, auto_ack=False)    print(' [*] Waiting for messages. To exit press CTRL+C')    channel.start_consuming()if __name__ == "__main__":    start_consuming()

4.2.2 安全生产者(send_msg_safe.py)

import pikadef publish_message():    connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))    channel = connection.channel()    channel.queue_declare(queue='hello2', durable=True)    channel.basic_publish(exchange='', routing_key='hello2', body='Hello World!',                         properties=pika.BasicProperties(delivery_mode=2))    connection.close()if __name__ == "__main__":    publish_message()

运行命令:

python recv_msg_safe.pypython send_msg_safe.py

4.3 广播模式

4.3.1 广播消费者(fanout_receive.py)

import pikadef callback(ch, method, properties, body):    print(" [x] %r" % body)def start_consuming():    connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))    channel = connection.channel()    channel.exchange_declare(exchange='logs', exchange_type='fanout')    result = channel.queue_declare("", exclusive=True)    queue_name = result.method.queue    channel.queue_bind(exchange='logs', queue=queue_name)    print(' [*] Waiting for logs. To exit press CTRL+C')    channel.basic_consume(on_message_callback=callback, queue=queue_name, auto_ack=True)    channel.start_consuming()if __name__ == "__main__":    start_consuming()

4.3.2 广播生产者(fanout_send.py)

import pikaimport sysdef publish_message():    connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))    channel = connection.channel()    channel.exchange_declare(exchange='logs', exchange_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()if __name__ == "__main__":    publish_message()

运行命令:

python fanout_receive.pypython fanout_send.py

4.4 组播模式

4.4.1 组播消费者(direct_recv.py)

import pikaimport sysdef callback(ch, method, properties, body):    print(" [x] %r:%r" % (method.routing_key, body))def start_consuming():    connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))    channel = connection.channel()    channel.exchange_declare(exchange='direct_logs', exchange_type='direct')    result = channel.queue_declare("", exclusive=True)    queue_name = result.method.queue    binding_keys = sys.argv[1:]    if not binding_keys:        sys.stderr.write("Usage: %s [info] [warning] [error]\n" % sys.argv[0])        sys.exit(1)    for severity in binding_keys:        channel.queue_bind(exchange='direct_logs', queue=queue_name, routing_key=severity)    print(' [*] Waiting for logs. To exit press CTRL+C')    channel.basic_consume(on_message_callback=callback, queue=queue_name)    channel.start_consuming()if __name__ == "__main__":    start_consuming()

4.4.2 组播生产者(direct_send.py)

import pikaimport sysdef publish_message():    connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))    channel = connection.channel()    channel.exchange_declare(exchange='direct_logs', exchange_type='direct')    routing_key = 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=routing_key, body=message)    print(" [x] Sent %r:%r" % (routing_key, message))    connection.close()if __name__ == "__main__":    publish_message()

运行命令:

python direct_recv.py infopython direct_send.py info

4.5 更细致的Topic模式

4.5.1 Topic消费者(topic_recv.py)

import pikaimport sysdef callback(ch, method, properties, body):    print(" [x] %r:%r" % (method.routing_key, body))def start_consuming():    connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))    channel = connection.channel()    channel.exchange_declare(exchange='topic_logs', exchange_type='topic')    result = channel.queue_declare("", exclusive=True)    queue_name = result.method.queue    binding_keys = sys.argv[1:]    if not binding_keys:        print("sys.argv[0]", sys.argv[0])        sys.stderr.write("Usage: %s [binding_key]...\n" % sys.argv[0])        sys.exit(1)    for binding_key in binding_keys:        channel.queue_bind(exchange='topic_logs', queue=queue_name, routing_key=binding_key)    print(' [*] Waiting for logs. To exit press CTRL+C')    channel.basic_consume(on_message_callback=callback, queue=queue_name)    channel.start_consuming()if __name__ == "__main__":    start_consuming()

4.5.2 Topic生产者(topic_send.py)

import pikaimport sysdef publish_message():    connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))    channel = connection.channel()    channel.exchange_declare(exchange='topic_logs', exchange_type='topic')    routing_key = sys.argv[1] if len(sys.argv) > 1 else 'anonymous.info'    message = ' '.join(sys.argv[2:]) or 'Hello World!'    channel.basic_publish(exchange='topic_logs', routing_key=routing_key, body=message)    print(" [x] Sent %r:%r" % (routing_key, message))    connection.close()if __name__ == "__main__":    publish_message()

运行命令:

python topic_recv.py infopython topic_send.py info

4.6 Remote Procedure Call (RPC) 模式

4.6.1 RPC客户端(rpc_client.py)

import pikaimport uuidimport timeclass FibonacciRpcClient:    def __init__(self):        self.response = None        credentials = pika.PlainCredentials('guest', 'guest')        self.connection = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))        self.channel = self.connection.channel()        result = self.channel.queue_declare("", exclusive=True)        self.callback_queue = result.method.queue        self.channel.basic_consume(queue=self.callback_queue, auto_ack=True, on_message_callback=self.on_response)        def on_response(self, ch, method, props, body):        if self.corr_id == props.correlation_id:            self.response = body    def call(self, n):        self.corr_id = str(uuid.uuid4())        self.channel.basic_publish(exchange='', routing_key='rpc_queue',                               properties=pika.BasicProperties(reply_to=self.callback_queue, correlation_id=self.corr_id),                               body=str(n))        while self.response is None:            self.connection.process_data_events()            time.sleep(0.5)        return int(self.response)fibonacci_rpc = FibonacciRpcClient()response = fibonacci_rpc.call(5)print(" [.] Got %r" % response)

4.6.2 RPC服务器(rpc_server.py)

import pikaimport timedef fib(n):    if n == 0:        return 0    elif n == 1:        return 1    else:        return fib(n-1) + fib(n-2)def on_request(ch, method, props, body):    n = int(body)    print(" [.] fib(%s)" % n)    response = fib(n)    ch.basic_publish(exchange='', routing_key=props.reply_to,                   properties=pika.BasicProperties(correlation_id=props.correlation_id),                   body=str(response))channel = pika.BlockingConnection(pika.ConnectionParameters(host='localhost'))channel.channel.queue_declare(queue='rpc_queue')channel.basic_consume(queue="rpc_queue", auto_ack=True, on_message_callback=on_request)print(" [x] Awaiting RPC requests")channel.start_consuming()

运行命令:

python rpc_server.pypython rpc_client.py

转载地址:http://uqafk.baihongyu.com/

你可能感兴趣的文章
python | nupic,一个强大的 处理时间序列的Python 库!
查看>>
python | orange3,一个神奇的 Python 库!
查看>>
python | pdfminer,一个神奇的 关于PDF 文件的 Python 库!
查看>>
python | pendulum,一个有趣的 日期和时间 Python 库!
查看>>
python | pluginbase,一个神奇的 关于插件框架 的Python 库!
查看>>
python | ply,一个无敌的 词法和语法分析工具 的Python 库!
查看>>
python | py2exe,一个超酷的 Python 库!
查看>>
python | pyautogui,一个超酷的 Python 库!
查看>>
python | pybaobabdt,一个超强的 决策树可视化 Python 库!
查看>>
python | pycco,一个神奇的 Python 库!
查看>>
python | pyg2plot,一个有趣的 数据可视化 Python 库!
查看>>
python | pymc,一个超强的 Python 库!
查看>>
python | pynsist,一个强大的 Python 库!
查看>>
python | pyparsing,一个强大的 Python 库!
查看>>
python | pyqtgraph,一个神奇的 Python 库!
查看>>
python读取文本文件数据
查看>>
python | Python mock对象与测试替身
查看>>
python | Python pandas实现数据追加和合并的最佳方法
查看>>
python | Python 中检查一个数字是否是三态数
查看>>
python | Python 蒙特卡洛模拟
查看>>