乐趣区

关于运维:同程旅行基于-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 信息,可退出社区交换群,上面是钉钉群,欢送大家加群留言。

退出移动版