JMS学习(八)-ActiveMQ Consumer 使用 push 还是 pull 获取消息
ActiveMQ是一个消息中间件,对于消费者而言有两种方式从消息中间件获取消息:
①Push方式:由消息中间件主动地将消息推送给消费者;②Pull方式:由消费者主动向消息中间件拉取消息。看一段官网对Push方式的解释:
To be able to achieve high performance it is important to stream messages to consumers as fast as possible
so that the consumer always has a buffer of messages, in RAM, ready to process
- rather than have them explicitly pull messages from the server which adds significant latency per message.
采用Push方式,可以尽可能快地将消息发送给消费者(stream messages to consumers as fast as possible)
而采用Pull方式,会增加消息的延迟,即消息到达消费者的时间有点长(adds significant latency per message)。
但是,Push方式会有一个坏处:如果消费者的处理消息的能力很弱(一条消息需要很长的时间处理),而消息中间件不断地向消费者Push消息,消费者的缓冲区可能会溢出。
那ActiveMQ是怎么解决这个问题的呢?那就是 prefetch limit
prefetch limit 规定了一次可以向消费者Push(推送)多少条消息。
Once the prefetch limit is reached, no more messages are dispatched to the consumer
until the consumer starts sending back acknowledgements of messages (to indicate that the message has been processed)
当推送消息的数量到达了perfetch limit规定的数值时,消费者还没有向消息中间件返回ACK,消息中间件将不再继续向消费者推送消息。
那prefetch limit的值设置为多少合适?视具体的应用场景而定。
If you have very few messages and each message takes a very long time to process
you might want to set the prefetch value to 1 so that a consumer is given one message at a time.
如果消息的数量很少(生产者生产消息的速率不快),但是每条消息 消费者需要很长的时间处理,那么prefetch limit设置为1比较合适。这样,消费者每次只会收到一条消息,当它处理完这条消息之后,向消息中间件发送ACK,此时消息中间件再向消费者推送下一条消息。
prefetch limit 设置成0意味着什么?
Specifying a prefetch limit of zero means the consumer will poll for more messages, one at a time,
instead of the message being pushed to the consumer.
意味着此时,消费者去轮询消息中间件获取消息。不再是Push方式了,而是Pull方式了。即消费者主动去消息中间件拉取消息。
perfetch limit是“消息预取”的值,这是针对消息中间件如何向消费者发消息 而设置的。与之相关的还有针对 消费者以何种方式向消息中间件返回确认ACK(响应):比如消费者是每次消费一条消息之后就向消息中间件确认呢?还是采用“延迟确认”---即采用批量确认的方式(消费了若干条消息之后,统一再发ACK)。这就是 Optimized Acknowledge
ActiveMQ can acknowledge receipt of messages back to the broker in batches (to improve performance).
引用 一段话:“如果prefetchACK为true,那么prefetch必须大于0;当prefetchACK为false时,你可以指定prefetch为0以及任意大小的正数。
不过,当prefetch=0是,表示consumer将使用PULL(拉取)的方式从broker端获取消息,broker端将不会主动push消息给client端,直到client端发送PullCommand时;
当prefetch>0时,就开启了broker push模式,此后只要当client端消费且ACK了一定的消息之后,会立即push给client端多条消息。”
那么,在程序中如何采用Push方式或者Pull方式呢?
从是否阻塞来看,消费者有两种方式获取消息。同步方式和异步方式。
同步方式使用的是ActiveMQMessageConsumer的receive()方法。而异步方式则是采用消费者实现MessageListener接口,监听消息。
使用同步方式receive()方法获取消息时,prefetch limit即可以设置为0,也可以设置为大于0
prefetch limit为零 意味着:“receive()方法将会首先发送一个PULL指令并阻塞,直到broker端返回消息为止,这也意味着消息只能逐个获取(类似于Request<->Response)”
prefetch limit 大于零 意味着:“broker端将会批量push给client 一定数量的消息(<= prefetch),client端会把这些消息(unconsumedMessage)放入到本地的队列中,只要此队列有消息,那么receive方法将会立即返回,当一定量的消息ACK之后,broker端会继续批量push消息给client端。”
当使用MessageListener异步获取消息时,prefetch limit必须大于零了。因为,prefetch limit 等于零 意味着消息中间件不会主动给消费者Push消息,而此时消费者又用MessageListener被动获取消息(不会主动去轮询消息)。这二者是矛盾的。
此外,还有一个要注意的地方,即消费者采用同步获取消息(receive方法) 与 异步获取消息的方法(MessageListener) ,对消息的确认时机是不同的。
具体可参考:这篇文章。
参考资料: ActiveMQ消息传送机制以及ACK机制详解
JMS学习(八)-ActiveMQ Consumer 使用 push 还是 pull 获取消息的更多相关文章
- JMS学习十一(ActiveMQ Consumer高级特性之独有消费者(Exclusive Consumer))
一.简介 Queue中的消息是按照顺序被分发到consumers的.然而,当你有多个consumers同时从相同的queue中提取消息时, 你将失去这个保证.因为这些消息是被多个线程并发的处理.有的时 ...
- JMS学习八(ActiveMQ消息持久化)
ActiveMQ的消息持久化机制有JDBC,AMQ,KahaDB和LevelDB,还有一种内存存储的方式,由于内存不属于持久化范畴,而且如果使用内存队列,可以考虑使用更合适的产品,如ZeroMQ.所以 ...
- JMS学习(五)--ActiveMQ中的消息的持久化和非持久化 以及 持久订阅者 和 非持久订阅者之间的区别与联系
一,消息的持久化和非持久化 ①DeliveryMode 这是传输模式.ActiveMQ支持两种传输模式:持久传输和非持久传输(persistent and non-persistent deliver ...
- JMS学习(六)-ActiveMQ的高可用性实现
原文地址:http://www.cnblogs.com/hapjin/p/5663024.html 一,ActiveMQ高可用性的架构 ActiveMQ的高可用性架构是基于Master/Slave 模 ...
- JMS学习(七)-ActiveMQ消息的持久存储方式之KahaDB存储
一,介绍 自ActiveMQ5.4以来,KahaDB成为了ActiveMQ默认的持久化存储方式.相比于原来的AMQ存储方式,官方宣称KahaDB使用了更少的文件描述符,并且提供了更快的存储恢复机制. ...
- 消息队列-推/拉模式学习 & ActiveMQ及JMS学习
一种分类是推和拉 . 还有一种分类是 Queue 和 Pub/Sub . 先看的这一篇:http://blog.csdn.net/heyutao007/article/details/50131089 ...
- ActiveMQ基本详解与总结& 消息队列-推/拉模式学习 & ActiveMQ及JMS学习
转自:https://www.cnblogs.com/Survivalist/p/8094069.html ActiveMQ基本详解与总结 基本使用可以参考https://www.cnblogs.co ...
- JMS学习之路(一):整合activeMQ到SpringMVC
JMS的全称是Java Message Service,即Java消息服务.它主要用于在生产者和消费者之间进行消息传递,生产者负责产生消息,而消费者负责接收消息.把它应用到实际的业务需求中的话我们可以 ...
- JMS学习之路(一):整合activeMQ到SpringMVC 转载:http://www.cnblogs.com/xiaochangwei/p/5426639.html
JMS的全称是Java Message Service,即Java消息服务.它主要用于在生产者和消费者之间进行消息传递,生产者负责产生消息,而消费者负责接收消息.把它应用到实际的业务需求中的话我们可以 ...
随机推荐
- ThreadPoolExecutor参数
1.ThreadPoolExecutor个参数的意义(类上的注释内容) * @param corePoolSize the number of threads to keep in the* pool ...
- 让 VAGRANT 启动并运行起来
这是一个帮助你快速入门Vagrant的初级教程.官方文档也可以很好的帮助你入门,但是本文更针对完全零基础的初学者并且会对某些问题直接切入正题. 本文在任何方面都不会取代官方文档,而且我建议读完本文的人 ...
- Angular $scope和$rootScope
<!DOCTYPE html><html ng-app='myModule'><head lang="en"> <meta charset ...
- Angular require(抄别的)
require参数的值可以用下面的前缀进行修饰,这会改变查找控制器时的行为:?如果在当前指令中没有找到所需要的控制器,会将null作为传给link函数的第四个参数.^如果添加了^前缀,指令会在上游的指 ...
- python中常用的九种数据预处理方法分享
Spyder Ctrl + 4/5: 块注释/块反注释 本文总结的是我们大家在python中常见的数据预处理方法,以下通过sklearn的preprocessing模块来介绍; 1. 标准化(St ...
- python学习笔记八——字典的方法
4.3.3 字典的方法 字典的常用方法可以极大地提高编程效率.keys()和values()分别返回字典的key列表和value列表.例: dict={"a":"appl ...
- SVG to Image in js
SVG to Image in js SVG to Image https://image.online-convert.com/convert-to-svg https://stackoverflo ...
- jmeter 创建web测试计划
测试用例: 1 创建5个用户发送请求到2个web页面: 2 发送3次请求 总请求=5*2*3=30 创建这个测试计划需要用到以下元素:thread groups / http request / ht ...
- Lodop在页面获取打印机列表 选择打印机预览
利用GET_PRINTER_COUNT,获取打印机个数,然后用GET_PRINTER_NAME(intPrinterIndex);循环获取打印机名称,添加到list列表里,可以让用户在页面就选择打印机 ...
- scrapy 简单爬虫实验
利用python的模块requests来爬取百度搜索出来的url 使用环境为python3 #!/use/bin/env python # -*- coding:utf-8 -*- import re ...