本文参考资料:
源码:https://github.com/apache/incubator-rocketmq
RocketMQ搭建:http://www.tuicool.com/articles/a2eaei
RocketMQ集群搭建:http://blog.csdn.net/aspnetandjava/article/details/53393937
RocketMQ 客户端最佳实践: https://yq.aliyun.com/articles/66128
kafka与RocketMQ 可靠性比较: http://blog.csdn.net/daiyutage/article/details/52053688
RocketMQ 关键特性: https://yq.aliyun.com/articles/66110?spm=5176.8067842.tagmain.112.qUh6Mn
Rocketmq源码分析(一)整体架构:https://yq.aliyun.com/articles/61141?spm=5176.8067842.tagmain.161.qUh6Mn
-
背景
15年年中做资金池(商家结算系统,主要是进行商家薪资核算,如核算订单收入,押金,奖励、扣款等)时为了和上层交易系统,订单中心等1级服务解耦,使用到家MQ,具体的设计方案如下:
解决问题:
- 和上游系统解耦:资金池系统即便出现性能问题,也不会引起上游系统雪崩;
- 削峰填谷:之前方案是对外暴露dubbo接口,但是由于上游各交易系统会定期开启多线程调用,薪资这边操作多(记录支付或商家退款信息,记录快照,记录差额,统计薪资,流入账户),且使用了事务,RT时间长,虽使用乐观锁及分布式式锁来保证的数据一致性,但是错误率很高,漏单较多,对账耗时多;使用MQ后,容错能力大大提高,并发也不再成为瓶颈;
- 可以信赖:处理58同城的业务数据在千万数据量级以上,消息堆积,消息投递实时性上经过实践检验;
-
问题
但是在使用中确实发现不少问题,尤其是16年普华永道审计前自检发现,有一小部分订单推送后丢失了,且存在部分订单金额错误了;虽然金额较小,迅速修复了数据,通过了审计,但是对我的触动比较大:
- 给商家的工资存在多发,少发的可能,总之账不平了,少不了花很多时间同财务&运营解释 ;
- 如果错误订单多,数据修复耗时长,金额大可能公司年报就发不出来了,事情就大了;
- 漏洞继续存在,要花很多时间去做对账程序,核对数据;
虽然通过对账方式解决了漏单,错单的问题,但抱着对MQ深深疑问,在没有拿到到家MQ的源码情况下,结合测试及线上问题排查:
- 到家MQ存在消息丢失的可能,原因也是各种: (1).消息未从producer 端成功发送:网络异常等原因(即便使用SEND方法执行成功,但由于网络等原因,未发送成功) (2).comsumer订阅了消息,但是网络超时、系统异常(comsumer 接收线程未正常shudown,进程被kill -9 等)原因等消息未被正确处理上 (3).其他原因(可能在网络传输或者消息在MQ队列中由于重启等丢失了);
- 在并发情况下,消息顺序无法得到保障。如:订单先支付又马上退款,资金池收到的消息顺序可能就是:1.退款消息 2.支付消息。
-
进一步学习
和RocketMQ相比如下:
特性 | 到家MQ | RocketMQ |
持久化 | mysql | 硬盘 |
单机吞吐量 | 较低 | 万级(高) |
多语言支持 | 支持c++,java,net | 仅JAVA |
消息延迟 | 较差 | 毫秒级(较高) |
消息可靠性 | 非常高(分布式) | 非常高(分布式) |
消息丢失 | 少量 | 理论上基本不丢失 |
事务 | 不支持 | 支持 |
定时消息 | 不支持 | 支持 |
顺序消息 | 不支持 | 支持 |
消息回溯,查询 | 不支持 | 不支持(暂无进口支持) |
REQUEST-REPLY | 不支持 | 不支持(因订阅和发布均是异步,不支持) |
API完整性 | 高 | 高 |
进一步发现功能上相对单一:1.无重试机制 2.不支持定时消息 3.也不支持消息查询,消息回溯等。
-
总结
尽管到家MQ还有些不足,但是对于自研的MQ能在业务上基本需求,技术上很值得肯定,同时也很期待后续的版本迭代。