同程旅行基于 RocketMQ 高可用架构实践

简介: 我们在几年前决定引入 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 ,确保消息的严格一致

原文链接
本文为阿里云原创内容,未经允许不得转载。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/513058.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

重磅 | 数据库自治服务DAS论文入选全球顶会SIGMOD,领航“数据库自动驾驶”新时代

简介&#xff1a; 近日&#xff0c;智能数据库和DAS团队研发的智能调参ResTune系统论文被SIGMOD 2021录用&#xff0c;SIGMOD是数据库三大顶会之首&#xff0c;是三大顶会中唯一一个Double Blind Review的&#xff0c;其权威性毋庸置疑。 近日&#xff0c;智能数据库和DAS团队…

如何帮用户管好云账本?阿里云数据库助力收钱吧 | 甲子光年

简介&#xff1a; “收钱吧到账100万”成为普通商家最想听到的声音。 你有多久没摸过现金了&#xff1f; 中国互联网络信息中心发布的第47次《中国互联网络发展状况统计报告》数据显示&#xff0c;截至2020年12月&#xff0c;我国移动支付用户规模达到8.54亿&#xff1b;中国人…

Redis 会遇到的「坑」,你踩过几个?

作者 | Magic Kaito来源 | 水滴与银弹这篇文章&#xff0c;我想和你聊一聊在使用 Redis 时&#xff0c;可能会踩到的「坑」。如果你在使用 Redis 时&#xff0c;也遇到过以下这些「诡异」的场景&#xff0c;那很大概率是踩到「坑」了&#xff1a;明明一个 key 设置了过期时间&a…

bert 多义词_自然语言处理:Bert及其他

以下内容主要参考了文末列出的参考文献&#xff0c;在此表示感谢&#xff01;2018年被认为是NLP技术的new era的开始。在这一年&#xff0c;提出了多种有创新性的技术&#xff0c;而且最后的集大成者Bert在NLP的多项任务中屠榜&#xff0c;造成的震撼不比当初神经网络初次在Ima…

谈谈JVM内部锁升级过程

简介&#xff1a; 对象在内存中的内存布局是什么样的&#xff1f;如何描述synchronized和ReentrantLock的底层实现和重入的底层原理&#xff1f;为什么AQS底层是CASvolatile&#xff1f;锁的四种状态和锁升级过程应该如何描述&#xff1f;Object o new Object() 在内存中占用多…

JetBrains发布两项重要更新:基于IDE的远程开发解决方案、轻量级编辑器Fleet

近日&#xff0c;JetBrains 对外发布两项重要产品更新&#xff1a;专为云端和其他服务器打造的远程开发解决方案&#xff0c;以及轻量级编辑器Fleet。 为IntelliJ 平台引入远程开发支持 在近期陆续发布的2021.3 版本的各 IDE 中&#xff0c;JetBrains 向 IntelliJ 平台添加了远…

Hologres揭秘:优化COPY,批量导入性能提升5倍+

简介&#xff1a; 揭秘Hologres优化COPY的技术原理&#xff0c;实现批量导入性能提升5倍 Hologres&#xff08;中文名交互式分析&#xff09;是阿里云自研的一站式实时数仓&#xff0c;这个云原生系统融合了实时服务和分析大数据的场景&#xff0c;全面兼容PostgreSQL协议并与…

io密集型和cpu密集型_一次说明白Python爬虫中多线程,多进程,异步IO编程

图/文&#xff1a;迷神我们在Python爬虫中&#xff0c;重要的是讲究速度&#xff0c;如果有10万或者100万Url地址&#xff0c;写过爬虫的都会知道&#xff0c;那估计是非常慢的。我们的Python爬虫一般IO密集型业务&#xff0c;Python爬虫程序需要发起网络请求&#xff0c;必然就…

【详谈 Delta Lake 】系列技术专题 之 湖仓一体( Lakehouse )

简介&#xff1a; 本文翻译自大数据技术公司 Databricks 针对数据湖 Delta Lake 的系列技术文章。众所周知&#xff0c;Databricks 主导着开源大数据社区 Apache Spark、Delta Lake 以及 ML Flow 等众多热门技术&#xff0c;而 Delta Lake 作为数据湖核心存储引擎方案给企业带来…

移动网络安装测试软件,家宽众测中国移动手机版(在线宽带网速测试器)V2.0.3 去广告版...

家宽众测中国移动手机版(在线宽带网速测试器)是一款手机宽带网速测试工具&#xff0c;用户可以通过本软件加入中国移动的宽带评测活动各种&#xff0c;反映家中宽带的具体使用情况&#xff0c;支持在线报名参加&#xff0c;抢先体验则有奖励赠送哦&#xff0c;欢迎来下载。软件…

如何删除第一张单页_单页网站-网站建设中独有的风景线

在这个网页技术飞速发展的时代&#xff0c;单页网站由于其自身的特点已经形成了一种独有的风景线。从本质上来说&#xff0c;单页网站就是只有一个页面&#xff0c;滚动长页面来显示相关的网站内容&#xff0c;网站所有菜单都链接到主页相应的部位。一些前卫的客户已经开始关注…

service注入为null_如何解决quartz调度时候,job中的service为null的问题?

在需要用到调度任务的时候&#xff0c;发现job中的通过依赖注入的service对象为null.如下&#xff1a;Component public class ExpiredOrderJob implements Job {Autowiredprivate EmployeeService employeeService; //这里的service对象为nullOverridepublic void execute(Job…

工作7年,我的10条经验总结

简介&#xff1a; 作者是一名很普通的技术工程师&#xff0c;从14年毕业到现在工作了7年。本文将与大家分享一些在职场中的道理和经验&#xff0c;希望能对大家有所启发和帮助。 作者 | 抱真 来源 | 阿里技术公众号 前言 简单做个自我介绍&#xff0c;我是一名很普通的技术工…

从能用到好用,GIS信创如何做到行稳致远?

艾瑞咨询集团出品的《2021年中国信创产业研究报告》中提到&#xff0c;信创内涵体现在“从‘关键环节、部分市场’走向‘全产业链、全行业’的信息技术升级&#xff0c;构建中国自主的IT标准和生态”。本文将从GIS信创的3大关键技术战略出发&#xff0c;解析当下如何快速突破发…

CPU静默数据错误:存储系统数据不丢不错的设计思考

简介&#xff1a; 对于数据存储系统来说&#xff0c;保障数据不丢不错是底线&#xff0c;也是数据存储系统最难的部分。据统计&#xff0c;丢失数据中心10天的企业&#xff0c;93%会在1年内破产。那么如果想要做到数据不丢不错&#xff0c;我们可以采取怎样的措施呢&#xff1f…

分计算iv值_筛选变量的指标—IV值

这一期咱们聊聊筛选变量的指标——IV值。计算公式如下&#xff1a;看公式有没有很熟悉&#xff0c;大家没有看错&#xff0c;其中一部分就是WOE的计算公式。区别就在于WOE是对一个变量的每个分组的计算&#xff0c;IV值是对一个变量的统计指标。如上图所示&#xff0c;当前使用…

无需 Dockerfile 的镜像构建:BuildPack vs Dockerfile

作者 | Addo Zhang来源 | 云原生指北过去的工作中&#xff0c;我们使用微服务、容器化以及服务编排构建了技术平台。为了提升开发团队的研发效率&#xff0c;我们同时还提供了 CICD 平台&#xff0c;用来将代码快速的部署到 Openshift&#xff08;企业级的 Kubernetes&#xff…

android studio json插件_热门Android Studio 插件,这里是Top 20

Android Studio是Google基于IntelliJ开发的一款功能强大的开发工具&#xff0c;它具有构建出色Android应用所需要的一切。借助基于IntelliJ IDEA的强大的功能&#xff0c;插件非常丰富。正确的使用插件可以帮助你提高工作效率&#xff0c;更智能&#xff0c;更快。但是&#xf…

云原生时代,企业多活容灾体系构建思路与最佳实践

简介&#xff1a; 对于云原生的概念解读&#xff0c;大家经常会听到微服务、容器这些&#xff0c;那么这些技术跟企业容灾到底有什么样的关系&#xff1f;其实容灾的需求各行各业都有&#xff0c;比如金融行业对于容灾也有强烈的需求。但是怎么把容灾和多活能力构建起来&#x…

MaxCompute 挑战使用SQL进行序列数据处理

简介&#xff1a; MaxCompute 挑战使用SQL进行序列数据处理 --而不是用MR和函数 日常编写数据加工任务&#xff0c;主要的方法就是使用SQL。第一是因为自己对SQL掌握的比较好&#xff08;十多年数据开发经验&#xff0c;就这几个关键字&#xff0c;也不敢跟别人说自己不行&…