RabbitMQ 队列消息持久化

假如消息队列test里面还有消息等待消费者(consumers)去接收,但是这个时候服务器端宕机了,这个时候消息是否还在?

1、队列消息非持久化

服务端(producer):

import pika

# 声明一个socket 实例
connect = pika.BlockingConnection(pika.ConnectionParameters("localhost"))
# 声明一个管道
channel = connect.channel()
# 声明queue名称为test
channel.queue_declare(queue="test") #RabbitMQ的消息永远不会被直接发送到队列中,它总是需要经过一次交换
channel.basic_publish(exchange='',
routing_key="test",
body="hello word") print("Sent 'hello world'") connect.close()

客户端(consumers):

import pika
import time
# 声明socket实例
connect = pika.BlockingConnection(pika.ConnectionParameters("localhost"))
# 声明一个管道 虽然在之前的produce代码中声明过一次管道,
# 但是在不知道produce中的管道是否运行之前(如果未运行,consumers中也不声明的话就会报错),
# 在consumers中也声明一次是一种正确的做法
channel = connect.channel() #声明queue
channel.queue_declare(queue="test") #回调函数
def callback(ch, method, properites, body):
time.sleep(30)
print("-----", ch, method, properites, body)
print("Received %r" % body)
ch.basic_ack(delivery_tag=method.delivery_tag) # 手动确认收到消息,添加手动确认时,no_ack必须为False,不然就会报错 channel.basic_consume(callback,
queue="test",
no_ack=False) print("Waiting for messages")
#这个start只要一启动,就一直运行,它不止收一条,而是永远收下去,没有消息就在这边卡住
channel.start_consuming()

上面的服务端和客户端声明queue的方式都是非持久的

channel.queue_declare(queue="test") 

①服务端先发送往test队列里发送两条消息

②通过运行--services.msc进入服务重新启动RabbitMQ

③再次查看消息队列queue中的消息数量

通过小实验可以看出,非持久声明的queue,在服务端宕机后,消息队列queue和消息都不复存在了

2、队列消息持久化:

①队列持久化很简单,只需要在服务端(produce)声明queue的时候添加一个参数:

channel.queue_declare(queue='shuaigaogao', durable=True)  # durable=True 持久化

②仅仅持久化队列是没有意义的,还需要多消息进行持久化

channel.basic_publish(exchange="",
routing_key="shuaigaogao", #queue的名字
body="hello world", #body是要发送的内容
properties=pika.BasicProperties(delivery_mode=2,) # make message persistent=>使消息持久化的特性
)

③最后一步,在服务端队列消息都持久化了之后需要在客户端声明queue的时候也持久化

channel.queue_declare(queue='shuaigaogao', durable=True)

这样就算再传递消息过程中,服务端的发生宕机,消息和队列也不会丢失

小结:

  1. RabbitMQ在服务端没有声明队列和消息持久化时,队列和消息是存在内存中的,服务端宕机了,队列和消息也不会保留。
  2. 服务端声明持久化,客户端想接受消息的话,必须也要声明queue时,也要声明持久化,不然的话,客户端执行会报错。

RabbitMQ 消息公平分发

如果Rabbit只管按顺序把消息发到各个消费者身上,不考虑消费者负载的话,很可能出现,一个机器配置不高的消费者那里堆积了很多消息处理不完,同时配置高的消费者却一直很轻松。为解决此问题,可以在各个消费者端,配置perfetch=1,意思就是告诉RabbitMQ在我这个消费者当前消息还没处理完的时候就不要再给我发新消息了。

channel.basic_qos(prefetch_count=1)

通俗的讲就是消费者有多大本事,就干多少活,消费者处理的越慢,其消息分配分发的就少,反之消费者消息处理的多,处理的快,就可以多向这个消费者分配一些消息。服务端给客户端发消息的时候,先检查一下,这个消费者现在还有多少消息,如果处理的消息超过1条,就不给这个消费者发送消息了

队列消息持久化+公平分发示列:

服务端:

import pika

# 声明一个socket 实例
connect = pika.BlockingConnection(pika.ConnectionParameters("localhost"))
# 声明一个管道
channel = connect.channel()
# 声明queue名称为test
channel.queue_declare(queue="test", durable=True) # 队列持久化 #RabbitMQ的消息永远不会被直接发送到队列中,它总是需要经过一次交换
channel.basic_publish(exchange='',
routing_key="test",
body="hello word",
properties=pika.BasicProperties(delivery_mode=2,)) # 消息持久化 print("Sent 'hello world'") connect.close()

客户端:

import pika
import time
# 声明socket实例
connect = pika.BlockingConnection(pika.ConnectionParameters("localhost"))
# 声明一个管道 虽然在之前的produce代码中声明过一次管道,
# 但是在不知道produce中的管道是否运行之前(如果未运行,consumers中也不声明的话就会报错),
# 在consumers中也声明一次是一种正确的做法
channel = connect.channel() #声明queue
channel.queue_declare(queue="test", durable=True) #回调函数
def callback(ch, method, properites, body):
time.sleep(30)
print("-----", ch, method, properites, body)
print("Received %r" % body)
ch.basic_ack(delivery_tag=method.delivery_tag) # 手动确认收到消息,添加手动确认时,no_ack必须为False,不然就会报错 channel.basic_qos(prefetch_count=1) # 在消息消费之前加上消息处理配置 channel.basic_consume(callback,
queue="test",
no_ack=False) print("Waiting for messages")
#这个start只要一启动,就一直运行,它不止收一条,而是永远收下去,没有消息就在这边卡住
channel.start_consuming()

  

【python】-- RabbitMQ 队列消息持久化、消息公平分发的更多相关文章

  1. python RabbitMQ队列使用(入门篇)

    ---恢复内容开始--- python RabbitMQ队列使用 关于python的queue介绍 关于python的队列,内置的有两种,一种是线程queue,另一种是进程queue,但是这两种que ...

  2. python RabbitMQ队列使用

    python RabbitMQ队列使用 关于python的queue介绍 关于python的队列,内置的有两种,一种是线程queue,另一种是进程queue,但是这两种queue都是只能在同一个进程下 ...

  3. python RabbitMQ队列/redis

    RabbitMQ队列 rabbitMQ是消息队列:想想之前的我们学过队列queue:threading queue(线程queue,多个线程之间进行数据交互).进程queue(父进程与子进程进行交互或 ...

  4. 持久化和公平分发.py

    1.消息持久化在实际应用中,可能会发生消费者收到Queue中的消息,但没有处理完成就宕机(或出现其他意外)的情况,这种情况下就可能会导致消息丢失.为了避免这种情况发生,我们可以要求消费者在消费完消息后 ...

  5. RabbitMQ队列,Redis\Memcached缓存

    RabbitMQ RabbitMQ是一个在AMQP基础上完整的,可复用的企业消息系统. MQ全称Message Queue,消息队列(MQ)是一种应用程序对应用程序的通信方式.应用程序通过读写出入队列 ...

  6. RabbitMQ基本用法、消息分发模式、消息持久化、广播模式

    RabbitMQ基本用法 进程queue用于同一父进程创建的子进程间的通信 而RabbitMQ可以在不同父进程间通信(例如在word和QQ间通信) 示例代码 生产端(发送) import pika c ...

  7. 【RabbitMQ学习记录】- 消息队列存储机制源码分析

    本文来自 网易云社区 . RabbitMQ在金融系统,OpenStack内部组件通信和通信领域应用广泛,它部署简单,管理界面内容丰富使用十分方便.笔者最近在研究RabbitMQ部署运维和代码架构,本篇 ...

  8. Day10-Python3基础-协程、异步IO、redis缓存、rabbitMQ队列

    内容目录: Gevent协程 Select\Poll\Epoll异步IO与事件驱动 Python连接Mysql数据库操作 RabbitMQ队列 Redis\Memcached缓存 Paramiko S ...

  9. python---RabbitMQ(1)简单队列使用,消息依次分发(一对一),消息持久化处理

    MQ全称为Message Queue, 消息队列(MQ)是一种应用程序对应用程序的通信方法.应用程序通过读写出入队列的消息(针对应用程序的数据)来通信,而无需专用连接来链接它们.消息传递指的是程序之间 ...

随机推荐

  1. 每日英语:The Upside of Favoritism

    As the head of the entertainment division of a major public-relations firm in New York, Janelle was ...

  2. 李洪强iOS开发之数据存储

    李洪强iOS开发之数据存储 iOS应用数据存储的常用方式 1.lXML属性列表(plist)归档 2.lPreference(偏好设置) 3.lNSKeyedArchiver归档(NSCoding) ...

  3. Django rest_framework 认证源码流程

    一.请求到来后,都要先执行dispatch方法 dispatch根据请求方式的不同触发get/post/put/delete等方法 注意,APIView中的dispatch方法有很多的功能 def d ...

  4. 裸的lcs

    最长公共子串,裸的复杂度N^2 #include<bits/stdc++.h> using namespace std; ][]; int main() { ]; ]; scanf(&qu ...

  5. JVM系统性能监控总结

    (1) uptime 查看系统运行时间.连接数(终端连接数).平均负载 (2) top 查看CPU.内存.交换空间使用情况,可以看到当前系统性能进程消耗资源情况 (3) vmstat 统计系统CPU. ...

  6. 缓存技术PK:选择Memcached还是Redis(转)

    [IT168 技术]要Memcached还是要Redis?在构建一款现代且由数据库驱动的Web应用程序并希望使其拥有更为出色的性能表现时,这个问题总会时不时出现.并给每一位开发人员带来困扰.在考虑对应 ...

  7. 网卡优化RPS/RFS

    网卡优化 RSS receive side scaling,网卡多队列,需要硬件支持.网卡接收到网络数据包后,要发送一个硬件中断,通知CPU取数据包.默认配置,都是由CPU0去做. RPS recei ...

  8. ES6学习笔记(1,let和const)

    在介绍let和const之前我们先复习一下相关的知识点. 关于函数作用域 开发过程中,在ES6(ECMA2015)标准推出之前,声明变量的方式一直都是var,而变量的作用域一般也只在函数内部,即函数作 ...

  9. 002Maven_第一个Maven演示

    第一步. 首先建立Hello项目同时建立Maven约定的目录结构 Hello     --src     -----main     ----------java     ----------reso ...

  10. Hibernate Annotations 注解

    Hibernate Annotations 注解 对于org.hibernate.annotations与org.hibernate.persistence,它的注释比如Columns,可是不知道怎么 ...