持久化和公平分发.py
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的更多相关文章
- 【python】-- RabbitMQ 队列消息持久化、消息公平分发
RabbitMQ 队列消息持久化 假如消息队列test里面还有消息等待消费者(consumers)去接收,但是这个时候服务器端宕机了,这个时候消息是否还在? 1.队列消息非持久化 服务端(produc ...
- RabbitMQ简单应用の公平分发(fair dipatch)
公平分发(fair dipatch)和轮询分发其实基本一致,只是每次分发的机制变了,由原来的平均分配到现在每次只处理一条消息 1.MQ连接工厂类Connection package com.mmr.r ...
- RabbitMQ (四) 工作队列之公平分发
上篇文章讲的轮询分发 : 1个队列,无论多少个消费者,无论消费者处理消息的耗时长短,大家消费的数量都一样. 而公平分发,又叫 : 能者多劳,顾名思义,处理得越快,消费得越多. 生产者 public c ...
- rabbitmq 公平分发和消息接收确认(转载)
原文地址:http://www.jianshu.com/p/f63820fe2638 当生产者投递消息到broker,rabbitmq把消息分发到消费者. 如果设置了autoAck=true 消费者会 ...
- RabbitMQ学习第二记:工作队列的两种分发方式,轮询分发(Round-robin)和 公平分发(Fair dispatch)
1.什么是RabbitMQ工作队列 我们在应用程序使用消息系统时,一般情况下生产者往队列里插入数据时速度是比较快的,但是消费者消费数据往往涉及到一些业务逻辑处理导致速度跟不上生产者生产数据.因此如果一 ...
- RabbitMQ的轮询模式和公平分发
一.常用的消息模式 我们在工作的使用中,经常会遇到多个消费者监听同一个队列的情况,模型如下图所示: 当有多个消费者时,我们的消息会被哪个消费者消费呢,我们又该如何均衡消费者消费信息的多少呢: 主要有两 ...
- 工作队列work queues 公平分发(fair dispatch) And 消息应答与消息持久化
生产者 package cn.wh.work; import cn.wh.util.RabbitMqConnectionUtil; import com.rabbitmq.client.Channel ...
- Java使用RabbitMQ之公平分发
发送消息: package org.study.workfair; import com.rabbitmq.client.Channel; import com.rabbitmq.client.Con ...
- RabbitMQ 均衡调度(公平分发机制)
均衡调度是针对Consumer来说的.现在有两个Consumer请求同一个队列的消息.RabbitMQ会将序号为奇数的消息发给第一个Consumer,会将序号为偶数的消息发送给第二个Consumer. ...
随机推荐
- beego 自定义控制器与路由
框架浅析 这是之前使用bee创建的webapp目录层级结构: ├── conf 配置文件 │ └── app.conf ├── controllers 控制器 │ └── default.go ├── ...
- Problem 2285 迷宫寻宝
http://acm.fzu.edu.cn/problem.php?pid=2285 Problem Description 洪尼玛今天准备去寻宝,在一个n*n (n行, n列)的迷宫中,存在着一个入 ...
- MySQL之数据导入导出
日常开发中,经常会涉及到对于数据库中数据的导入与导出操作,格式也有很多: TXT,CSV,XLS,SQL等格式,所以,在此总结一下,省的总是百度查询. 一 导出 1) 常用的方式就是使用现成的工具例如 ...
- phantomjs 了解
转自:http://www.cnblogs.com/lei0213/ PhantomJS是一个无界面的,可脚本编程的WebKit浏览器引擎.它原生支持多种web 标准:DOM 操作,CSS选择器,JS ...
- Java 找不到或者无法加载主类
1 测试Test 类的时候突然遇到一个很奇怪的问题,网上搜了很多资料才找到解决办法,大多数情况是因为类加了包名编译,执行的时候没有到包下去执行.与我遇到的情况不一样. 问题:写了一个测试类Test,在 ...
- [转帖]Linux 的静态库与动态库
Linux下的静态库与动态库 2017年02月18日 09:17:13 LLZK_ 阅读数:10257 标签: linux动态库静态库区别使用 更多 个人分类: Linux学习笔记 所属专栏: Lin ...
- oninput和onchange的区别
菜鸟教程: oninput事件:HTML5标准事件 当用户向<input>中尝试输入时执行JavaScript: <input type="text" oninp ...
- 字符串正则替换replace第二个参数是函数
zepto中 //将字符串转成驼峰式的格式 camelize = function (str) { return str.replace(/-+(.)?/g, function (match, chr ...
- PHP爬虫框架Snoopy的使用
参考文档: http://ibillxia.github.io/blog/2010/08/10/php-connecting-tool-snoopy-introduction-and-applicat ...
- vs code安装
vs code是一款文本编辑器,开源,是前端界的vs,而Dreamweaver适合入门. user版本的一些系统分区文件夹无法创建,可能存在语言显示问题.一般用户建议使用system版. 下载链接:h ...