--喜欢记得关注我哟【shoshana】--
前记:
5月12号参加了JAVA开发者大会,就<拍拍贷消息系统原理及应用> 作者:李乘胜老师 关于PMQ的分享整理一下笔记以及笔记的思考 和复制PPT。如有需要也可以私我PPT。
拍拍贷消息系统:以下简称PMQ,
PS,据说下半年PMQ会提交APACHE进入开源,蛮好的,期待ing~
第一部分:笔记
1.PMQ 目前线上支持1000个应用,高峰 27+亿,日常高峰 2W TPS
2.针对 MQ的常见问题
(1) 消息发送慢怎么办?
批量发送?
(2) 消息堆积了,如何快速知晓与处理?
扩容-->添加线程数-->添加消费实例-->批量pull消费
(3)失败消息如何处理?
独立的失败队列-->重试-->重试失败,指定重试
(4)如保保障消息的高可靠?
利用数据库的高可用
PS :这块在分享时一开始就提出问题,然后进入大量干货分享,然后最后在PPT的结束又重新回顾解答这些问题。
哈哈,个人觉得有两个点是值得借鉴的,
带着问题去听分享,这是个不错的idea,可以激发听众的兴趣。
结束时还重新回顾了一开始的问题,这是首尾呼应吗,紧扣主题 ,让我想到了写作文,李老师文笔不错。
3.MQ消费 push ,pull的区别: push broker无状态,pull broker有状态。
扩展:
关于有状态无状态:
(1). 在系统设计上,遵循的原则还是简单为主
通过简单的设计来满足我们的业务需求
如何简单?非特殊情况,都设计成无状态的吧
(2). 有状态服务可以比较容易地实现事务,在不需要考虑水平扩展时,是比较好的选择
无状态服务的优势在于可以很方便地水平伸缩,但是在实现事务时,需要做一些额外的动作
可以通过剥离session等方法,将一个有状态服务,转换成无状态服务
兴趣选择性扩展:
4.PMQ利用mysql的集群-实现消息的可靠性。
扩展:
关于MQ的存储模型选择补充
MQ的类型来看,存储模型分两种:
-
- 需要持久化(ActiveMQ,RabbitMQ,Kafka,RocketMQ)
- 不需要持久化(ZeroMQ)
持久化MQ的存储模型,因为现在大多数的MQ都是支持持久化存储,而且业务上也大多需要MQ有持久存储的能力,能大大增加系统的高可用性,下面几种存储方式:
-
- 分布式KV存储(levelDB,RocksDB,redis)
- 传统的文件系统
- 传统的关系型数据库
这几种存储方式从效率来看, 文件系统>kv存储>关系型数据库,因为直接操作文件系统肯定是最快的,而关系型数据库一般的TPS都不会很高,我印象中Mysql的写不会超过5Wtps(现在不确定最新情况),所以如果追求效率就直接操作文件系统。
但是如果从可靠性和易实现的角度来说,则是关系型数据库>kv存储>文件系统,消息存在db里面非常可靠,但是性能会下降很多,所以具体的技术选型都是需要根据自己的业务需求去考虑。
兴趣选择性扩展:
5.PMQ支持多语言,java,python,.net 对于多语音的支持一般解决方案 proxy代理。
扩展:
支持异构语言的通信:就是搞个代理java的proxy的实际去消费,消费消息后做个http转发,这样可以支持任意语言,本来是具体语言去消费,现在统一由java代理消费,代理拿到消息发起一个远程调用,就用restful就可以
常用的跨语言通信方案:
-
- 基于SOAP消息格式的WebService
- 基于JSON消息格式的RESTful 服务
以上两种方案的弊端:
-
- XML体积太大,解析性能极差
- JSON体积相对较小,解析相对较快,但表达能力较弱
现在比较流行的跨语言通信方案:
- Google protobuf (http://code.google.com/p/protobuf)
- Apache Thrift (http://thrift.apache.org/)
- Apache Avro (http://avro.apache.org/)
JNA
JNA是建立在JNI技术基础之上的一个Java类库,它使您可以方便地使用java直接访问动态链接库中的函数。
原来使用JNI,你必须手工用C写一个动态链接库,在C语言中映射Java的数据类型。
JNA中,它提供了一个动态的C语言编写的转发器,可以自动实现Java和C的数据类型映射,你不再需要编写C动态链接库。
也许这也意味着,使用JNA技术比使用JNI技术调用动态链接库会有些微的性能损失。但总体影响不大,因为JNA也避免了JNI的一些平台配置的开销。
兴趣选择性扩展:
跨语言通信方案的比较—Thrift、Protobuf和Avro
6.M重复解决的途径:幂等性设计
扩展:
造 成消息重复的根本原因是:网络不可达。只要通过网络交换数据,就无法避免这个问题。所以解决这个问题的办法就是绕过这个问题。那么问题就变成了:如果消费端收到两条一样的消息,应该怎样处理?
(1)消费端处理消息的业务逻辑保持幂等性
(2)保证每条消息都有唯一编号且保证消息处理成功与去重表的日志同时出现
第1条很好理解,只要保持幂等性,不管来多少条重复消息,最后处理的结果都一样。第2条原理就是利用一张日志表来记录已经处理成功的消息的ID,如果新到的消息ID已经在日志表中,那么就不再处理这条消息。
第1条解决方案,很明显应该在消费端实现,不属于消息系统要实现的功能。第2条可以消息系统实现,也可以业务端实现。正常情况下出现重复消息的概率其实很小,如果由消息系统来实现的话,肯定会对消息系统的吞吐量和高可用有影响,所以最好还是由业务端自己处理消息重复的问题,这也是RocketMQ不解决消息重复的问题的原因。
如何保证MQ的消费是幂等性的,需要结合具体的业务来看 :
比如你拿个数据要写库,你先根据主键查一下,如果这数据都有了,你就别插入了,update一下好吧
比如你是写redis,那没问题了,反正每次都是set,天然幂等性
比如你不是上面两个场景,那做的稍微复杂一点,你需要让生产者发送每条数据的时候,里面加一个全局唯一的id,类似订单id之类的东西,然后你这里消费到了之后,先根据这个id去比如redis里查一下,之前消费过吗?如果没有消费过,你就处理,然后这个id写redis。如果消费过了,那你就别处理了,保证别重复处理相同的消息即可。
还有比如基于数据库的唯一键来保证重复数据不会重复插入多条,拿到数据的时候,每次重启可能会有重复,因为kafka消费者还没来得及提交offset,重复数据拿到了以后我们插入的时候,因为有唯一键约束了,所以重复数据只会插入报错,不会导致数据库中出现脏数据
兴趣选择性扩展:
7.创建Topic根据调用量分配机器(一台或多台),灵活资源合理匹配。
8.消息隔离:token
9.失败消息:自己新建一个失败topic(普通的topic)--自动重发--补偿
10.延时消息 -cluster,forking
11.消息 查看 出错->支持暂停消息 重新消费->动态调整偏移量。
12.操作审记 ->记录日志->保证权限控制->安全
13.客户端消息两种:配置xml,代码配置java
和dubbo是类似的设计
14.消费失败告警:
是否可扩展功能-自动暂停任务。
第二部分:PPT
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
2018-05-24 Java多线程基础:进程和线程之由来
2018-05-24 Java并发编程:线程间协作的两种方式:wait、notify、notifyAll和Condition
2018-05-24 Java并发编程:Timer和TimerTask
2018-05-24 Java并发编程:Callable、Future和FutureTask
2018-05-24 Java并发编程:CountDownLatch、CyclicBarrier和Semaphore
2018-05-24 Java并发编程:线程池的使用
2018-05-24 Java并发编程:阻塞队列