简介: 咱们在几年前决定引入 MQ 时,市场上曾经有不少成熟的解决方案,比方 RabbitMQ , ActiveMQ,NSQ,Kafka 等。思考到稳定性、保护老本、公司技术栈等因素,咱们抉择了 RocketMQ。
背景介绍
为何抉择 RocketMQ
咱们在几年前决定引入 MQ 时,市场上曾经有不少成熟的解决方案,比方 RabbitMQ , ActiveMQ,NSQ,Kafka 等。思考到稳定性、保护老本、公司技术栈等因素,咱们抉择了 RocketMQ:
- 纯 Java 开发,无依赖,应用简略,呈现问题能 hold;
- 通过阿里双十一考验,性能、稳定性能够保障;
- 性能实用,发送端:同步、异步、单边、延时发送;生产端:音讯重置,重试队列,死信队列;
- 社区沉闷,出问题能及时沟通解决。
应用状况
- 次要用于削峰、解耦、异步解决;
- 已在火车票、机票、酒店等外围业务宽泛应用,扛住微小的微信入口流量;
- 在领取、订单、出票、数据同步等外围流程宽泛应用;
- 每天 1000+ 亿条音讯周转。
下图是 MQ 接入框架图
因为公司技术栈起因,client sdk 咱们提供了 java sdk;对于其余语言,收敛到 http proxy,屏蔽语言细节,节约保护老本。依照各大业务线,对后端存储节点进行了隔离,互相不影响。
MQ 双核心革新
之前单机房呈现过网络故障,对业务影响较大。为保障业务高可用,同城双核心革新提上了日程。
为何做双核心
- 单机房故障业务可用;
- 保证数据牢靠:若所有数据都在一个机房,一旦机房故障,数据有失落危险;
- 横向扩容:单机房容量无限,多机房可分担流量。
双核心计划
做双核心之前,对同城双核心计划作了些调研,次要有冷(热)备份、双活两种。(过后社区 Dledger 版本还没呈现,Dledger 版本齐全可做为双核心的一种可选计划。)
1)同城冷(热)备份
两个独立的 MQ 集群, 用户流量写到一个主集群,数据实时同步到备用集群,社区有成熟的 RocketMQ Replicator 计划,须要定期同步元数据,比方主题,生产组,生产进度等。
2)同城双活
两个独立 MQ 集群,用户流量写到各自机房的 MQ 集群,数据互相不同步。
平时业务写入各自机房的 MQ 集群,若一个机房挂了,能够将用户申请流量全副切到另一个机房,音讯也会生产到另一个机房。
对于双活计划,须要解决 MQ 集群域名。
1)若两个集群用一个域名,域名能够动静解析到各自机房。此形式要求生产、生产必须在同一个机房。如果生产在 idc1,生产在 idc2,这样生产、生产各自连贯一个集群,没法生产数据。
2)若一个集群一个域名,业务方改变较大,咱们之前对外服务的集群是单核心部署的,业务方曾经大量接入,此计划推广较艰难。
为尽可能减少业务方改变,域名只能持续应用之前的域名,最终咱们采纳一个 Global MQ 集群,跨双机房,无论业务是单核心部署还是双核心部署都不影响;而且只有降级客户端即可,无需改变任何代码。
双核心诉求
- 就近准则:生产者在 A 机房,生产的音讯存于 A 机房 broker;消费者在 A 机房,生产的音讯来自 A 机房 broker。
- 单机房故障:生产失常,音讯不丢。
- broker 主节点故障:主动选主。
就近准则
简略说,就是确定两件事:
- 节点(客户端节点,服务端节点)如何判断本人在哪个 idc;
- 客户端节点如何判断服务端节点在哪个 idc。
如何判断本人在哪个 idc?
1) ip 查问
节点启动时能够获取本身 ip,通过公司外部的组件查问所在的机房。
2)环境感知
须要与运维同学一起配合,在节点装机时,将本身的一些元数据,比方机房信息等写入本地配置文件,启动时间接读写配置文件即可。
咱们采纳了第二个计划,无组件依赖,配置文件中 logicIdcUK 的值为机房标记。
客户端节点如何辨认在同一个机房的服务端节点?
客户端节点能够拿到服务端节点的 ip 以及 broker 名称的,因而:
- ip 查问:通过公司外部组件查问 ip 所在机房信息;
- broker 名称减少机房信息:在配置文件中,将机房信息增加到 broker 名称上;
- 协定层减少机房标识:服务端节点向元数据系统注册时,将本身的机房信息一起注册。
绝对于前两者,实现起来略简单,改变了协定层,咱们采纳了第二种与第三种联合的形式。
就近生产
基于上述剖析,就近生产思路很清晰,默认优先本机房就近生产;
若本机房的服务节点不可用,能够尝试扩机房生产,业务能够依据理论须要具体配置。
就近生产
优先本机房生产,默认状况下又要保障所有音讯能被生产。
队列调配算法采纳按机房调配队列
- 每个机房音讯均匀分给此机房生产端;
- 此机房没生产端,平分给其余机房生产端。
伪代码如下:
Map<String, Set> mqs = classifyMQByIdc(mqAll);
Map<String, Set> cids = classifyCidByIdc(cidAll);
Set<> result = new HashSet<>;
for(element in mqs){result.add(allocateMQAveragely(element, cids, cid)); //cid 为以后客户端
}
生产场景次要是生产端单边部署与双边部署。
单边部署时,生产端默认会拉取每个机房的所有音讯。
双边部署时,生产端只会生产本人所在机房的音讯,要留神每个机房的理论生产量与生产端的数量,防止出现某一个机房生产端过少。
单机房故障
- 每组 broker 配置
一主两从,一主一从在一机房,一从在另一机房;某一从同步完音讯,音讯即发送胜利。
- 单机房故障
音讯生产跨机房;未生产音讯在另一机房持续被生产。
故障切主
在某一组 broker 主节点呈现故障时,为保障整个集群的可用性,须要在 slave 当选主并切换。要做到这一点,首先得有个 broker 主故障的仲裁零碎,即 nameserver(以下简称 ns)元数据系统(相似于 redis 中的哨兵)。
ns 元数据系统中的节点位于三个机房(有一个第三方的云机房,在云上部署 ns 节点,元数据量不大,延时能够承受),三个机房的 ns 节点通过 raft 协定选一个 leader,broker 节点会将元数据同步给 leader, leader 在将元数据同步给 follower。
客户端节点获取元数据时, 从 leader,follower 中均可读取数据。
切主流程
- 若 nameserver leader 监控到 broker 主节点异样, 并要求其余 follower 确认;半数 follower 认为 broker 节点异样,则 leader 告诉在 broker 从节点当选主,同步进度大的从节点选为主;
- 新选举的 broker 主节点执行切换动作并注册到元数据系统;
- 生产端无奈向旧 broker 主节点发送音讯。
流程图如下
切核心演练
用户申请负载到双核心,上面的操作先将流量切到二核心 — 回归双核心 — 切到一核心。确保每个核心均可承当全量用户申请。
先将用户流量全副切到二核心
流量回归双核心,并切到一核心
回顾
- 全局 Global 集群
- 就近准则
- 一主二从,写过半音讯即及写入胜利
- 元数据系统 raft 选主
- broker 主节点故障,主动选主
MQ 平台治理
即便零碎高性能、高可用,假使轻易应用或应用不标准,也会带来各种各样的问题,减少了不必要的保护老本,因而必要的治理伎俩不可或缺。
目标
让零碎更稳固
- 及时告警
- 疾速定位、止损
治理哪些方面
主题 / 生产组治理
- 申请应用
生产环境 MQ 集群,咱们敞开了主动创立主题与生产组,应用前须要先申请并记录主题与生产组的我的项目标识与应用人。一旦呈现问题,咱们可能立刻找到主题与生产组的负责人,理解相干状况。若存在测试,灰度,生产等多套环境,能够一次申请多个集群同时失效的形式,防止一一集群申请的麻烦。
- 生产速度
为防止业务忽略发送大量无用的音讯,有必要在服务端对主题生产速度进行流控,防止这个主题挤占其余主题的解决资源。
- 音讯积压
对音讯沉积敏感的生产组,应用方可设置音讯沉积数量的阈值以及报警形式,超过这个阈值,立刻告诉应用方;亦可设置音讯沉积工夫的阈值,超过一段时间没被生产,立刻告诉应用方。
- 生产节点掉线
生产节点下线或一段时间无响应,须要告诉给应用方。
客户端治理
- 发送、生产耗时检测
监控发送 / 生产一条音讯的耗时,检测出性能过低的利用,告诉应用方着手革新以晋升性能;同时监控音讯体大小,对音讯体大小均匀超过 10 KB 的我的项目,推动我的项目启用压缩或音讯重构,将音讯体管制在 10 KB 以内。
- 音讯链路追踪
一条音讯由哪个 ip、在哪个工夫点发送,又由哪些 ip、在哪个工夫点生产,再加上服务端统计的音讯接管、音讯推送的信息,形成了一条简略的音讯链路追踪,将音讯的生命周期串联起来,应用方可通过查问 msgId 或当时设置的 key 查看音讯、排查问题。
- 过低或有隐患版本检测
随着性能的一直迭代,sdk 版本也会降级并可能引入危险。定时上报 sdk 版本,推动应用方降级有问题或过低的版本。
服务端治理
- 集群衰弱巡检
如何判断一个集群是衰弱的?定时检测集群中节点数量、集群写入 tps、生产 tps,并模仿用户生产、生产音讯。
- 集群性能巡检
性能指标最终反映在解决音讯生产与生产的工夫上。服务端统计解决每个生产、生产申请的工夫,一个统计周期内,若存在肯定比例的音讯解决工夫过长,则认为这个节点性能有问题;引起性能问题的起因次要是零碎物理瓶颈,比方磁盘 io util 使用率过高,cpu load 低等,这些硬件指标通过夜鹰监控零碎主动报警。
- 集群高可用
高可用次要针对 broker 中 master 节点因为软硬件故障无奈失常工作,slave 节点主动被切换为 master,适宜音讯程序、集群完整性有要求的场景。
局部后盾操作展现
主题与生产组申请
生产,生产,沉积实时统计
集群监控
踩过的坑
社区对 MQ 零碎经验了长时间的改良与积淀,咱们在应用过程中也到过一些问题,要求咱们能从深刻理解源码,做到呈现问题心不慌,疾速止损。
- 新老生产端并存时,咱们实现的队列调配算法不兼容,做到兼容即可;
- 主题、生产组数量多,注册耗时过长,内存 oom,通过压缩缩短注册工夫,社区已修复;
- topic 长度判断不统一,导致重启丢音讯,社区已修复;
- centos 6.6 版本中,broker 过程假死,降级 os 版本即可。
MQ 将来瞻望
目前音讯保留工夫较短,不不便对问题排查以及数据预测,咱们接下来将对历史音讯进行归档以及基于此的数据预测。
- 历史数据归档
- 底层存储剥离,计算与存储拆散
- 基于历史数据,实现更多数据预测
- 服务端降级到 Dledger,确保音讯的严格统一
理解更多 RocketMQ 信息,可退出社区交换群,上面是钉钉群,欢送大家加群留言。
版权申明: 本文内容由阿里云实名注册用户自发奉献,版权归原作者所有,阿里云开发者社区不领有其著作权,亦不承当相应法律责任。具体规定请查看《阿里云开发者社区用户服务协定》和《阿里云开发者社区知识产权爱护指引》。如果您发现本社区中有涉嫌剽窃的内容,填写侵权投诉表单进行举报,一经查实,本社区将立即删除涉嫌侵权内容。