当前位置: 首页 > article >正文

python如何使用Rabbitmq

目录

一、Rabbitmq介绍

二、Rabbitmq的使用场景

1、异步处理

2、服务解耦

3、流量削峰

4、日志收集

5、发布订阅

6、任务调度

三、python如何使用Rabbitmq

1、安装依赖

2、基础使用

3、消息确认

4、消息持久化

5、公平调度

6、发布订阅

7、关键字发布


一、Rabbitmq介绍

RabbitMQ是一个开源的消息中间件,基于AMQP(Advanced Message Queue Protocol,高级消息队列协议)协议实现。RabbitMQ被广泛应用于各种应用场景,如异步任务处理、日志传输、实时消息推送等。在微服务架构中,RabbitMQ是一个常见的消息中间件选择,它可以帮助服务之间实现解耦和异步通信,提高系统的可扩展性和稳定性。RabbitMQ提供了一个简单的用户页面,用户可以监控和管理消息、队列、交换器、绑定等资源。通过管理界面,用户可以直观地了解系统的运行状态,并进行相应的配置和管理操作。

二、Rabbitmq的使用场景

1、异步处理

  • 在Web应用中,当用户提交表单时,可以将表单处理任务发送给RabbitMQ,由后台服务异步处理,从而提高用户界面的响应速度。
  • 在电商系统中,用户下单后,订单处理、库存更新、支付通知等任务可以异步执行,避免阻塞主线程。

2、服务解耦

  • 在微服务架构中,不同服务之间通过RabbitMQ进行通信,可以降低服务之间的耦合度,提高系统的可扩展性和可维护性。
  • 当某个服务需要升级或维护时,可以通过RabbitMQ实现服务的平滑过渡,而不会影响其他服务的正常运行。

3、流量削峰

  • 在高并发场景中,RabbitMQ可以作为一个缓冲层,接收并存储大量的请求,然后按照设定的速率将请求转发给后端服务,从而避免后端服务因过载而崩溃。
  • 通过RabbitMQ的限流和队列机制,可以有效地控制请求的速率和数量,保护后端服务的稳定性。

4、日志收集

  • RabbitMQ可以用于收集分散在各个服务器上的日志信息,将它们集中到一个或多个日志处理服务中,进行统一的分析和处理。
  • 通过RabbitMQ,可以实现日志的实时收集、分析和报警,提高系统的运维效率和故障排查能力。

5、发布订阅

  • 在需要向多个客户端推送消息的场景中,如实时通知、消息推送等,可以使用RabbitMQ的Fanout交换器将消息广播给所有绑定的队列。
  • 通过RabbitMQ的消息广播机制,可以实现实时、可靠的消息推送服务,提高用户体验。

6、任务调度

  • RabbitMQ可以与其他任务调度框架(如Quartz)结合使用,实现定时任务、延迟任务等复杂任务调度需求。
  • 通过RabbitMQ的任务调度功能,可以灵活地控制任务的执行时间和频率,提高系统的自动化程度和运行效率。

三、python如何使用Rabbitmq

Rabbitmq网址https://www.rabbitmq.com/tutorials

1、安装依赖

安装第三方库pika:pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pika

pip install -i https://pypi.tuna.tsinghua.edu.cn/simple pika

2、基础使用

生产者模型代码如下

import pika

# 生产者模型

connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))  # 连接本地的rabbitmq
channel = connection.channel()  # 连接通道
channel.queue_declare(queue='list')  #  创建一个名叫list的队列
channel.basic_publish(exchange='',
                      routing_key='list',  # 向那个队列发布信息
                      body='lol',# 发布的信息)
connection.close()  # 关闭连接

消费者代码如下

import pika

# 消费者模型

connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))  # 连接本地的rabbitmq
channel = connection.channel()  # 连接通道
channel.queue_declare(queue='list')  #  为确保队列存在,创建一个list队列

def callback(ch, method, properties, body):
    print(f" [x] 消费者接收到了任务 {body}")

channel.basic_consume(queue='list',on_message_callback=callback,auto_ack=True)  # 接收信息:queue表示监听的队列,on_message_callback表示接收到信息执行的函数,auto_ack表示默认执行回复
channel.start_consuming()   # 开启永无止境的循环监听该队列

3、消息确认

在队列中,执行任务可能需要几秒钟,您可能想知道如果 使用者启动一个长任务,并在完成之前终止。 使用我们当前的代码,一旦 RabbitMQ 将消息传递给消费者,它就会 立即将其标记为删除。在这种情况下,如果您终止 worker,则它刚刚处理的消息丢失了。调度的消息 对于这个尚未处理的特定 worker 来说,也会丢失。为了确保消息永远不会丢失,RabbitMQ 支持消息确认。ack由 consumer 告诉 RabbitMQ 已收到特定消息, 处理,并且 RabbitMQ 可以自由删除它。

这是由消费者来进行改变的,代码如下:

需要将auto_ack改为False,然后在回调函数里加入ch.basic_ack(delivery_tag=method.delivery_tag)

import pika

# 消费者模型

connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))  # 连接本地的rabbitmq
channel = connection.channel()  # 连接通道
channel.queue_declare(queue='list')  #  创建一个队列

def callback(ch, method, properties, body):
    print(f" [x] 消费者接收到了任务 {body}")
    ch.basic_ack(delivery_tag=method.delivery_tag) # 给队列回复进行确认

channel.basic_consume(queue='list2',on_message_callback=callback,auto_ack=False)  # auto_ack改为False
channel.start_consuming()  # 开启永无止境的循环监听该队列

4、消息持久化

如果 RabbitMQ 服务器 停止。

当 RabbitMQ 退出或崩溃时,它会忘记队列和消息 除非你告诉它不要这样做。需要做两件事来确保 消息不会丢失:我们需要将队列消息都标记为 耐用。然和把队列和消息保存在磁盘里。

这是有生产者来进行改变的,代码如下:

durable=True在创建队列时声明持久化,delivery_mode=pika.DeliveryMode.Persistent让信息做持久化

import pika

# 生产者模型

connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))  # 连接本地的rabbitmq
channel = connection.channel()  # 连接通道
channel.queue_declare(queue='list2',durable=True)  #  创建一个队列,durable=True表示队列支持持久化
channel.basic_publish(exchange='',
                      routing_key='list2',  # 向那个队列发布信息
                      body='lol',# 发布的信息
                      properties=pika.BasicProperties(
                          delivery_mode=pika.DeliveryMode.Persistent  # 让信息做持久化
                      ))
connection.close()  # 关闭连接

5、公平调度

您可能已经注意到,调度仍然没有完全工作 正如我们想要的那样。例如,在有两个 worker 的情况下,当所有 奇数消息很重,偶数消息很轻,一个 worker 将是 一直很忙,另一个几乎不做任何工作。井 RabbitMQ 对此一无所知,仍会 dispatch 消息均匀。

发生这种情况是因为 RabbitMQ 只是在消息 进入队列。它不看未确认的数量 消息。它只是盲目地调度每 n 条消息 到第 n 个消费者。

为了解决这个问题,我们可以使用带有 setup 的 channel 方法。它使用协议方法告诉 RabbitMQ 不要一次向 worker 提供多条消息。或者,换句话说,不要调度 向 worker 发送新消息,直到它处理并确认 上一个。相反,它会将其分派给下一个仍然不忙的 worker。

这是由消费者来进行改变的,代码如下:

channel.basic_qos(prefetch_count=1)进行闲置派发

import pika

# 消费者模型

connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))  # 连接本地的rabbitmq
channel = connection.channel()  # 连接通道
channel.queue_declare(queue='list')  #  为确保队列存在,创建一个list队列

def callback(ch, method, properties, body):
    print(f" [x] 消费者接收到了任务 {body}")

channel.basic_qos(prefetch_count=1)  # 闲置派发
channel.basic_consume(queue='list',on_message_callback=callback,auto_ack=True)  # 接收信息:queue表示监听的队列,on_message_callback表示接收到信息执行的函数,auto_ack表示默认执行回复
channel.start_consuming()   # 开启永无止境的循环监听该队列

6、发布订阅

发布订阅模式是将信息发布给所有的订阅者,其特点就是有交换机。

channel.exchange_declare(exchange='m1',exchange_type='fanout')声明一个交换机,类型为fanout,是将信息发给所有的订阅者

发布者代码如下:

import pika

connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))  # 连接rabbitmq
channel = connection.channel()  # 连接通道

channel.exchange_declare(exchange='m1',exchange_type='fanout')  # fanout:将信息发给所有的队列
channel.queue_declare(queue='')  #  创建一个队列,durable=True表示队列支持持久化
channel.basic_publish(exchange='m1',
                      routing_key='',  # 队列名称
                      body='lol',)# 发布的数据
connection.close()  # 关闭连接

订阅者代码如下:

import pika

connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))  # 连接rabbitmq
channel = connection.channel()

channel.exchange_declare(exchange='m1',exchange_type='fanout',)  # fanout:将信息发给所有的队列
result=channel.queue_declare(exclusive=True,queue='')  #  创建一个随机队列
queue_name=result.method.queue  # 拿到队列名字
print(queue_name)
channel.queue_bind(exchange='m1',queue=queue_name)  # 对exchange和queue进行绑定

def callback(ch, method, properties, body):
    print(f" [x] 消费者接收到了任务 {body}")


channel.basic_consume(queue=queue_name,on_message_callback=callback,auto_ack=True)
channel.start_consuming()  # 开启永无止境的循环监听该队列

7、关键字发布

关键字发布就是在发布订阅模式基础上,将不同信息发布给不同的订阅者。

channel.exchange_declare(exchange='m2',exchange_type='direct') ,声明一个交换机,交换机的类型为direct,将信息发布给指定的订阅者。

发布者代码如下:

import pika

connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))  # 连接rabbitmq
channel = connection.channel()  # 连接通道

channel.exchange_declare(exchange='m2',exchange_type='direct')  # direct:将信息发布给指定的订阅者
channel.queue_declare(queue='')  #  创建一个队列,durable=True表示队列支持持久化
channel.basic_publish(exchange='m2',
                      routing_key='hhq',  # 队列名称
                      body='cf',)# 发布的数据
connection.close()  # 关闭连接

订阅者代码如下:

import pika

connection = pika.BlockingConnection(pika.ConnectionParameters('localhost'))  # 连接rabbitmq
channel = connection.channel()

channel.exchange_declare(exchange='m2',exchange_type='direct')  # exchange:交易所的名称,fanout:将信息发给所有的队列
result=channel.queue_declare(exclusive=True,queue='')  #  创建一个随机队列
queue_name=result.method.queue  # 拿到队列名字
print(queue_name)
channel.queue_bind(exchange='m2',queue=queue_name,routing_key='hhq')  # 对exchange和queue进行绑定

def callback(ch, method, properties, body):
    print(f" [x] 消费者接收到了任务 {body}")


channel.basic_consume(queue=queue_name,on_message_callback=callback,auto_ack=True)
channel.start_consuming()  # 开启永无止境的循环监听该队列


http://www.kler.cn/a/392861.html

相关文章:

  • C++《继承》
  • css:盒子模型
  • 详解基于C#开发Windows API的SendMessage方法的鼠标键盘消息发送
  • Unity3D实现视频和模型融合效果
  • Scala入门基础(17.1)Set集习题
  • jmeter常用配置元件介绍总结之定时器
  • 从入门到了解C++系列-----内存管理 + 初步了解模板
  • CSS Modules是什么?
  • 【软件开发】Spring 面向切面编程(头歌作业)
  • 小程序租赁系统打造便捷租赁体验助力共享经济发展
  • HO-PEG-MACA中PEG的修饰使其提高了稳定性,有助于其在各种溶剂中保持稳定的性能。
  • 冗余连接2 hard题 代随C#写法
  • 【数据结构】10.线索二叉树
  • 【Verilog】case、casex、casez的区别
  • MySQL中的事务与锁
  • opencv入门学习总结
  • 游戏服务器和普通服务器的区别
  • Shell编程之正则表达式与文本处理器
  • 游程编码 (Run-length Encoding)详细解读
  • 【go从零单排】Logging
  • uniapp中多角色导致tabbar过多的解决方式
  • 基于Python的自然语言处理系列(59):MultiRetrievalQAChain 实现
  • 基于SSM的“汽车销售分析与管理系统”的设计与实现(源码+数据库+文档+PPT)
  • 笔记本电脑定期保养
  • SwiftUI开发教程系列 - 第十二章:本地化与多语言支持
  • 贪心算法入门(二)