1、消息持久化
在实际应用中,可能会发生消费者收到Queue中的消息,但没有处理完成就宕机(或出现其他意外)的情况,
这种情况下就可能会导致消息丢失。为了避免这种情况发生,我们可以要求消费者在消费完消息后发送一个回执给RabbitMQ,
RabbitMQ收到消息回执(Message acknowledgment)后才将该消息从Queue中移除;如果RabbitMQ没有收到回执并检测到消费者的RabbitMQ连接断开,
则RabbitMQ会将该消息发送给其他消费者(如果存在多个消费者)进行处理。这里不存在timeout概念,一个消费者处理消息时间再长也不会导致该消息被发送给其他消费者,除非它的RabbitMQ连接断开。 这里会产生另外一个问题,如果我们的开发人员在处理完业务逻辑后,忘记发送回执给RabbitMQ,这将会导致严重的bug——Queue中堆积的消息会越来越多;消费者重启后会重复消费这些消息并重复执行业务逻辑…千面是因为我们在消费者端标记了ACK=True关闭了它们,如果你没有增加ACK=True或者没有回执就会出现这个问题

生产者需要在发送消息的时候标注属性为持久化
# 在队列中添加消息
for i in range(100):
message = '%s Meassage '% i or "Hello World!"
# 发送消息
channel.basic_publish(exchange='',
routing_key='task_queue',
body=message,
properties=pika.BasicProperties(delivery_mode=2, )) # 标记属性消息为持久化消息需要客户端应答

# 发送消息结束,并关闭通道
print(" [x] Sent %r" % message)

消费者需要发送消息回执
# 订阅回调函数,这个订阅回调函数是由pika库来调用
def callback(ch, method, properties, body):
"""
:param ch: 通道对象
:param method: 消息方法
:param properties:
:param body: 消息内容
:return: None
"""
print(" [x] Received %r" % (body,))
time.sleep(2)
print(" [x] Done")

# 发送消息确认,确认交易标识符
ch.basic_ack(delivery_tag=method.delivery_tag)

我们通过命令查看哪些消费者没有回复ack确认
# Linux
rabbitmqctl list_queues name messages_ready messages_unacknowledged
# Windows
rabbitmqctl.bat list_queues name messages_ready messages_unacknowledged

2、队列持久化
如果我们希望即使在RabbitMQ服务重启的情况下,也不会丢失消息,我们可以将Queue与Message都设置为可持久化的(durable),这样可以保证绝大部分情况下我们的RabbitMQ消息不会丢失。
但依然解决不了小概率丢失事件的发生(比如RabbitMQ服务器已经接收到生产者的消息,但还没来得及持久化该消息时RabbitMQ服务器就断电了),如果我们需要对这种小概率事件也要管理起来,那么我们要用到事务。
由于这里仅为RabbitMQ的简单介绍,所以这里将不讲解RabbitMQ相关的事务。 这里我们需要修改下生产者和消费者设置RabbitMQ消息的持久化**[生产者/消费者]都需要配置**

channel.queue_declare(queue='task_queue', durable=True) # 队列持久化

3、公平分发
默认情况下RabitMQ会把队列里面的消息立即发送到消费者,无论该消费者有多少消息没有应答,也就是说即使发现消费者来不及处理,新的消费者加入进来也没有办法处理已经堆积的消息,因为那些消息已经被发送给老消费者了。类似下面的
在消费者中增加:`channel.basic_qos(prefetch_count=1)`
prefetchCount:会告诉RabbitMQ不要同时给一个消费者推送多于N个消息,即一旦有N个消息还没有ack,则该consumer将block掉,直到有消息ack。
这样做的好处是,如果系统处于高峰期,消费者来不及处理,消息会堆积在队列中,新启动的消费者可以马上从队列中取到消息开始工作。
公平分发.png

工作过程如下:
1. 消费者1接收到消息后处理完毕发送了ack并接收新的消息并处理
2. 消费者2接收到消息后处理完毕发送了ack并接收新的消息并处理
3. 消费者3接收到消息后一直处于消息中并没有发送ack不在接收消息一直等到消费者3处理完毕后发送ACK后再接收新消息

持久化和公平分发.py的更多相关文章

  1. 【python】-- RabbitMQ 队列消息持久化、消息公平分发

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

  2. RabbitMQ简单应用の公平分发(fair dipatch)

    公平分发(fair dipatch)和轮询分发其实基本一致,只是每次分发的机制变了,由原来的平均分配到现在每次只处理一条消息 1.MQ连接工厂类Connection package com.mmr.r ...

  3. RabbitMQ (四) 工作队列之公平分发

    上篇文章讲的轮询分发 : 1个队列,无论多少个消费者,无论消费者处理消息的耗时长短,大家消费的数量都一样. 而公平分发,又叫 : 能者多劳,顾名思义,处理得越快,消费得越多. 生产者 public c ...

  4. rabbitmq 公平分发和消息接收确认(转载)

    原文地址:http://www.jianshu.com/p/f63820fe2638 当生产者投递消息到broker,rabbitmq把消息分发到消费者. 如果设置了autoAck=true 消费者会 ...

  5. RabbitMQ学习第二记:工作队列的两种分发方式,轮询分发(Round-robin)和 公平分发(Fair dispatch)

    1.什么是RabbitMQ工作队列 我们在应用程序使用消息系统时,一般情况下生产者往队列里插入数据时速度是比较快的,但是消费者消费数据往往涉及到一些业务逻辑处理导致速度跟不上生产者生产数据.因此如果一 ...

  6. RabbitMQ的轮询模式和公平分发

    一.常用的消息模式 我们在工作的使用中,经常会遇到多个消费者监听同一个队列的情况,模型如下图所示: 当有多个消费者时,我们的消息会被哪个消费者消费呢,我们又该如何均衡消费者消费信息的多少呢: 主要有两 ...

  7. 工作队列work queues 公平分发(fair dispatch) And 消息应答与消息持久化

    生产者 package cn.wh.work; import cn.wh.util.RabbitMqConnectionUtil; import com.rabbitmq.client.Channel ...

  8. Java使用RabbitMQ之公平分发

    发送消息: package org.study.workfair; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Con ...

  9. RabbitMQ 均衡调度(公平分发机制)

    均衡调度是针对Consumer来说的.现在有两个Consumer请求同一个队列的消息.RabbitMQ会将序号为奇数的消息发给第一个Consumer,会将序号为偶数的消息发送给第二个Consumer. ...

随机推荐

  1. Windows和Linux的Jmeter分布式集群压力测试

    Windows的Jmeter分布式集群压力测试 原文:https://blog.csdn.net/cyjs1988/article/details/80267475 在使用Jmeter进行性能测试时, ...

  2. mac 中登陆mysql忘记密码解决办法

    1.打开终端,输入命令:cd /usr/local/mysql/bin 2.mysql -uroot -p,用这条命令登陆时报错信息: 报错:Enter password: ERROR 1045 (2 ...

  3. Spark 数据倾斜

    Spark 数据倾斜解决方案 2017年03月29日 17:09:58 阅读数:382 现象       当你的应用程序发生以下情况时你该考虑下数据倾斜的问题了: 绝大多数task都可以愉快的执行,总 ...

  4. hive安装详解

    1.安装MYSQL simon@simon-Lenovo-G400:~$ sudo apt-get install mysql-server simon@simon-Lenovo-G400:~$ su ...

  5. EXAMPLE FOR PEEWEE 多姿势使用 PEEWEE

    使用 PEEWEE 断断续续的差不多已经三个年头了,但是没有像这次使用这么多的特性和功能,所以这次一并记录一下,需要注意的地方和一些使用细节,之后使用起来可能会更方便. 因为是使用的 SQLAched ...

  6. playframework 编译打包过程失败

    root@mytest:/data# play war p2p-master --exclude tmp:logs:test:eclipse -o /data/a/sp2p~ _ _ ~ _ __ | ...

  7. python标准异常

    什么是异常? 异常即是一个事件,该事件会在程序执行过程中发生,影响了程序的正常执行.一般情况下,在Python无法正常处理程序时就会发生一个异常.异常是Python对象,表示一个错误.当Python脚 ...

  8. DELPHI中MDI子窗口的关闭 和打开

    Delphi中MDI子窗口的关闭方式默认为缩小而不是关闭,所以当你单击子窗口右上角的关闭按钮时会发觉该子窗口只是最小化,而不是你预期的那样被关闭.解决办法是在子窗口的OnClose事件处理过程中加入如 ...

  9. SQL约束(主键约束、外键约束、自动递增、不允许空值、值唯一、值默认、值限制范围)

    NOT NULL 不允许空值约束 NOT NULL 约束强制列不接受 NULL 值(NULL值就是没有值或缺值).NOT NULL 约束强制字段始终包含值,即不向字段添加值,就无法插入新记录或者更新记 ...

  10. 开发中遇到的css兼容问题

    1. overflow: scroll(平台兼容) 在Mac中的Chrome浏览器中,内容不超过容器时不会出现滚动条: 在Wins中的Chorme浏览器中,内容不超过容器时也会出现滚动条. 解决方法: ...