内容简介:这一节,咱们来聊聊nsq内部实现的几个有趣的细节。1、消息至少被投递一次这是nsq的
一些细节
这一节,咱们来聊聊nsq内部实现的几个有趣的细节。
1、消息至少被投递一次
这是nsq的 Guarantees 中的一个:
messages are delivered at least once
消息投递策略,是消息中间件的特有属性,不同的消息中间件,对投递策略的支持也不同。比如Kafka,就支持最多一次、至少一次、准确一次三种策略,而nsq,则只支持最常见的一种,也就是至少一次。
怎样保证消息至少被投递一次呢?
如果消费者收到消息,并成功执行,那么就给nsq返回 FIN
,代表消息已被成功执行,这时nsq就可以把内存中,也就是channel里的消息干掉;
而如果消费者处理消息时发生了异常,需要重试,那么就给nsq返回 REQ
,代表requeue,重新进入队列的意思,nsq就会把消息重新放到队列中,再次推送给消费者(这一次可能是另一个消费者实例)。如果消费者迟迟没有给nsq回响应,超过了最大等待时间,那么nsq也会将消息requeue.
所以,消费者必须保证操作的幂等性。
2、重试次数
nsq推送过来的消息里,有个 attempts
字段,代表着尝试的次数,一开始是1,每次客户端给nsq会 REQ
响应后,nsq再次推送过来的消息, attempts
都会加1,消费者可以按照自己的需要,对重试次数进行限制,比如希望最多尝试6次,那么就在消费者的处理逻辑中,判断 attempts <= 6
,是,则执行处理逻辑,否则,打印日志或者做其他处理,然后直接返回 FIN
,告诉nsq不要再重试。
3、消息无序性
消息是否有序,是消息中间件的特有属性。通过上面的分析,很明显,nsq的消息是无序的,这也在nsq官网里的 Guarantees 中有提到:
messages received are un-ordered
比如说channel A里现在有两条消息,M1和M2,M1先产生,M2后产生,channel A分别将M1和M2推送给了消费者 C1和C2,那么有可能C1比C2先处理完消息,这样是有序的;但也有可能,C2先处理了,这样M2就比M1先被处理,这样就是无序的。
正是由于这种一有消息就推送的策略,nsq里的消息处理是无序的。
4、push or pull
push还是pull,这也是在设计一个消息中间件时,必须要考虑的问题。Kafka用的是pull,而Nsq采取的是push。
相比于pull,push的好处不言而喻 —— 消息处理更加实时,一旦有消息过来,立即推送出去,而pull则具有不确定性,你不知道消费者什么时候有空过来pull,因此做不到实时消息处理。这也是有赞只把Kafka用在那些对实时性要求不高的业务上的原因,比如大数据统计。
也正是因为采用了push,nsq选择把消息放到内存中,只有当队列里消息的数量超过 --mem-queue-size
配置的限制时,才会对消息进行持久化,把消息保存到磁盘中,简称”刷盘“。
nsqd provides a configuration option –mem-queue-size that will determine the number of messages that are kept in memory for a given queue
而采用pull的Kafka,则直接把消息存储到磁盘。
push + 内存存储,or pull + 磁盘存储,这也是消息中间件设计时的一些套路。
当然,push机制也有缺陷,那就是当消费者很忙碌的时候,你还一直给它push,那只会逼良为娼,所以采用push的消息中间件,必须要进行流控。
关于push和pull的分析,后面再和大家深入探讨,有兴趣的同学可以先看下Kafka官网的这篇分析: Push vs Pull
5、流控
Nsq流控的方式非常简单,当消费者和nsq建立好连接,准备好接受消息时,会给nsq回一个 RDY
的响应,同时带上一个 rdy_count
,代表准备接受消息的数量,于是nsq会给消费者推送消息,每推送一条,对应连接的 rdy_count
就减1(如果是批量推送,则批量减),直到连接的 rdy_count
变成0,则不再继续推送消息。
当消费者觉得自己可以接收很多消息时,只需再发一次 RDY
命令,就可以更新连接的 rdy_count
,nsq就会继续给消费者推送消息。
在 java 客户端实现中,采取的策略是,如果发现已经处理完超过一半的消息,就再去发 RDY
消息,要求nsq送更多消息过来。
com.github.brainlag.nsq.NSQConsumer#processMessage:
参考
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持 码农网
猜你喜欢:- iOS刨根问底-深入理解GCD
- 刨根问底HTTP和WebSocket协议
- 刨根问底:深入研究 JavaScript 全局变量
- Java 如何实现优雅停服?刨根问底
- 刨根问底 HTTP 和 WebSocket 协议(上)
- 刨根问底 HTTP 和 WebSocket 协议(下)
本站部分资源来源于网络,本站转载出于传递更多信息之目的,版权归原作者或者来源机构所有,如转载稿涉及版权问题,请联系我们。
Chinese Authoritarianism in the Information Age
Routledge / 2018-2-13 / GBP 115.00
This book examines information and public opinion control by the authoritarian state in response to popular access to information and upgraded political communication channels among the citizens in co......一起来看看 《Chinese Authoritarianism in the Information Age》 这本书的介绍吧!