在公众号回复课程,免费获取JAVA全栈课程
做者 | 颜 群java
公众号 | 大数据和人工智能技术git
前两篇请戳:
web
本文解决最后两个问题:在使用MQ发送消息的过程当中,数据库
1.如何避免消息被重复消费编程
2.如何处理消息积压问题
服务器
如何避免消息被重复消费
在使用MQ的过程当中,各类异常状况均可能形成消息被重复消费。微信
例如不少类型的MQ都使用了offset(偏移量)记录每一个消息的序号,用于保证消息的顺序传输或者在出现灾难时可以从指定序号的消息恢复传输。网络
但试想如下场景:假设消息的处理逻辑是“先消费消息,再更新offset”,那么当消息刚刚被消费完毕但尚未来得及更新offset时就出现故障宕机,MQ就会在恢复启动时再次消费刚刚已经被消费过的消息,即出现了重复消费的状况。所以,不管是采用了哪一种协议的MQ,都须要思考如何避免消息被重复消费的问题。
实际上不只仅是MQ,在分布式系统的各个服务之间在相互调用时也须要解决“重复消费”的问题。例如在分布式秒杀系统中,若是“订单服务”成功调用了“支付服务”(即已经支付成功),但“支付服务”在做出响应时因为网络等缘由未能成功的响应“订单服务”,就会形成“订单服务”没法更新支付状态,最终就可能致使用户误觉得支付无效而从新再发起一次新的支付请求,从而致使用户重复消费的状况,如图所示。
可见这种“重复消费”问题广泛存在于各个分布式项目当中,所以必须妥善解决。好消息是,解决的思路也是通用的——能够借助“幂等性原则”解决。
幂等性原则是对调用服务次数的一种限制,即不管对某个服务提供的接口调用屡次或是一次,其结果都是相同的。
若是从功能的角度看来,任何一个操做都是CRUD中的一种。但对于“重复消费”这个问题而言,咱们只须要研究“增长”和“修改”两种操做,即“查询”和“删除”是不须要考虑幂等性的,由于“重复查”和“重复删”对逻辑而言是没有任何影响的。
“幂等性”是一个原则,它的具体实现方式也是五花八门。咱们本次主要介绍如何实现“增长”操做的幂等性,其核心思路主要有两种:使用数据库主键或去重表,以下所示。
根据数据库主键实现幂等性
核心就是利用主键(或惟一约束)的“惟一性”来保证插入数据的惟一。例如,在用户下单时,能够在“订单服务”中生成一个“订单id”,而后用此“订单id”的值再做为“支付服务”的“支付id”值。若是出现了重复支付,就会违反主键的惟一约束,从而避免重复消费的场景。固然,本段介绍的“直接用订单id做为支付id”只是为了说明这种使用主键实现幂等性的原理,在实际开发时,咱们也能够对这两个id进行一些映射处理,或者使用联合主键也是一种很好的实现策略。
根据去重表实现幂等性
可使用集合或者Redis构建一张“去重表”,表中存放的是全局惟一的id值。当用户每次发起请求时,先查看“去重表”中是否已有这次支付操做的id值,若是已有则直接返回“成功”;若是没有,就说明尚未进行实际的支付操做,此时就进行支付操做,并在支付成功后将id值写入“去重表”中,防止重复消费。
以上两种思路可以实现大部分“增长”操做的幂等性。对于“修改”操做,你们能够参考版本控制软件(如svn、git)中防止提交冲突的CAS算法。例如在svn中,当A用户修改并提交了数据后,B用户是没法直接提交的,不然就会出现冲突。这种版本控制的思路,就能够拿来实现“修改”操做的幂等性,即当第一次修改数据后,以后若是再次修改,就应该给予错误提示。
如何处理消息积压
消息队列自己是一种缓冲区,而缓冲区就会受自身容量的限制。例如在秒杀系统中,当用户请求的速度(生产者)大于服务器处理的速度(消费者)时,用户请求(消息)就会积压在队列中,而且随着时间的延长,积压的请求也会愈来愈多,若是不予处理就会溢出队列。
处理消息积压最直接的方式就是水平扩容,即增长Consumer和分区的数量,用集群的思路来处理。
或者,也能够将积压的消息以异步的方式写到其余多个新队列中,以后再由各个新队列分别处理。但要注意,为了防止宕机形成的消息丢失,必定要按期将消息进行持久化或者记录日志。
此外,还要区分当前系统的实时性,若是对实时性要求较低就把重点放在MQ的扩容上,若是实时性较高就须要提升并发性能。最后,当发生消息积压时,必定要认真审查已有代码和异常日志,检查一下MQ的并发值、吞吐量等重要参数,再看看是否存在反复批量重试的消息。
- 完 -
推荐阅读
▲
在“大数据和人工智能技术”聊天对话框回复如下关键词,可得到相关信息哟
回复【资料】获取JAVA全栈视频的配套资料
回复【最新课程】获取一门还没有公开的高级课程(不按期更换)
回复【提问】获取免费答疑方式
回复【课程】获取JAVA全栈视频教程 + 配套资料
回复【软件】获取经常使用的开发软件(逐步完善)
回复【亿级源码】获取本号做者出版的《亿级流量Java高并发与网络编程实战》一书配套源码
回复【javase】获取JAVA视频教程
回复【数据库】获取数据库视频教程
更多课程,逐步开放...
本文分享自微信公众号 - 大数据和人工智能技术(Big_Data-AI)。
若有侵权,请联系 support@oschina.cn 删除。
本文参与“OSC源创计划”,欢迎正在阅读的你也加入,一块儿分享。