历史原因,公司存在多个 MQ 同时使用的问题,我们中间件团队在去年下半年开始支持对 Kafka 和 Rabbit 能力的进行封装,初步能够完全支撑业务团队使用。

鉴于在之前已经基本完全实施 Kafka 管控平台、以及 Kafka 集群迁移管控,我们基本可以认为团队对于 Kafka 的把控能力初具规模。

因此,考虑到以下几点原因,我们决定对 RabbitMQ 不再做维护和支持。

原因

使用混乱和维护困难

基于我们的数据统计和分析发现,基本上没有服务使用我们自己封装的 RabbitMQ 能力,用到的基本上是spring-amqp或者原生的Rabbit 使用方式,存在使用混乱,方式不统一的问题,对于排查问题方面存在更多的问题。

另外考虑到对于 MQ 能力支持要做双份,Kafka 和 Rabbit 都要支持相同的功能,对于人力资源方面存在浪费,当然也由于本身目前没有对 RabbitMQ 非常精通的同学,所以对于维护能力这方面存在担忧。

分区容错问题

RabbitMQ 集群对于网络分区的容错性不高,根据调查发现,系统中 RabbitMQ 高可用方案使用镜像队列,而当 RabbitMQ 出现网络分区时,不同分区里的节点会认为不属于自身所在分区的节点都已经挂了,对于队列、交换器、绑定的操作仅对当前分区有效。

而且,如果原集群中配置了镜像队列,而这个镜像队列又牵涉两个或者更多个网络分区中的节点时,每一个网络分区中都会出现一个 master 节点,对于各个网络分区,此队列都是相互独立的。

在默认的情况下,架构本身存在脑裂的风险,在 3.1 版本下是无法自动恢复的,之后的版本才会自动探测网络分区,人工介入存在数据丢失的风险。

性能瓶颈

镜像队列解决了 Rabbit 高可用的问题,但是并不能增加负载和性能,线上曾经出现过 RabbitMQ 在高流量下的性能问题,就是因为队列由单个节点承载流量,在高并发情况在集群中单个节点存在性能瓶颈。

即便我们目前大部分场景下 MQ 流量不高,但是一旦出现问题,将成为整个系统的性能瓶颈。

另外我们对 Rabbit 做了一些性能方面的测试:

测试集群一共有 4 台磁盘节点,其中每台 16 核,如果我们不做 Sharding,单队列最高 TPS 在 5K 左右,如果是内存节点,官方可以给出的处理极限为 50K/s,如果做 Sharding,单队列处理能力可以达到 10K/s。

上述结论都是以消息能够被正常快速消费为前提,实际上在高流量或者大量消息积压的情况会导致集群性能急剧下降。

运维&管控

基于以上现有的问题和难点,我们决定对 Rabbit 进行全量迁移至 Kafka,以便能在业务高速发展过程中能够保障对于稳定性、高可用、高性能方面的追求。

在方法论和理论体系层面,我们对业务生产有三板斧:可灰度、可监控、可回滚。

同样,对于消息中间件平台运维我们希望有三板斧:可运维、可观测、可管控,那么目前基于 Kafka 的集群管控和 Kafka Manager 的能力我们已经基本做到了上述几点。

  1. 高可用:根据自身经验,Kafka 本身拥有极高的平台可用性
  2. 高性能:Kafka 可支撑极高的 TPS,并且支持水平扩展,可快速满足业务的流量增长需求
  3. 功能支持:在原有两个 MQ 能力基础上,基础支持顺序消息、延时消息、灰度消息、消息轨迹等
  4. 运维管控:基于 Kafka Manager 基础上进行二次开发,丰富管控能力和运维支撑能力,提供给开发、运维、测试更好的使用体验和运维能力。

模型对比

RabbitMQ

Exchange:生产者将消息发送到Exchange,由交换器将消息通过匹配Exchange Type、Binding Key、Routing Key后路由到一个或者多个队列中。

Queue:用于存储消息,消费者直接绑定Queue进行消费消息

Routing Key:生产者发送消息给 Exchange 会指定一个Routing Key。

Binding Key:在绑定Exchange与Queue时会指定一个Binding Key。

Exchange Type:

  • Direct:把消息路由到那些 Binding Key 和 Routing Key 完全匹配的队列中
  • Fanout:把消息转发给所有与它绑定的队列上,相当于广播模式
  • Topic:通过对消息的 Routing Key 和 Exchange、Queue 进行匹配,将消息路由给一个或多个队列,发布/订阅模式
  • Headers:根据消息的 Header 将消息路由到不同的队列,和 Routing Key 无关

Kafka

Topic:发送消息的主题,对消息的组织形式

Broker:Kafka 服务端

Consumer Group:消费者组

Partition:分区,topic 会由多个分区组成,通常每个分区的消息都是按照顺序读取的,不同的分区无法保证顺序性,分区也就是我们常说的数据分片sharding机制,主要目的就是为了提高系统的伸缩能力,通过分区,消息的读写可以负载均衡到多个不同的节点上

迁移方案

综上,我们将要对系统中所有使用RabbitMQ的服务进行迁移操作,整个迁移我们应该保证以下 3 点:

  1. 操作便捷,不能过于复杂,复杂会带来更多的不可控风险
  2. 风险可控,尽最大可能降低迁移对业务的影响
  3. 不影响业务正常运行

消费者双订阅

  1. 对消费者进行改造,同时监听 Rabbit 和 Kafka 消息
  2. 对生产者进行改造,迁移至Kafka发送消息
  3. 等待 Rabbit 遗留消息消费完毕之后,直接下线即可

优点:可以做到无损迁移

缺点:

  1. 需要同时维护两套监听代码,可能有大量的工作量,迁移完成之后还需要再进行一次老代码下线
  2. 消息无法保证顺序性

基于灰度单订阅

这是基于双订阅模式的优化,通过使用我们的灰度/蓝绿发布的能力,做到可以不双订阅,不用同时监听两个消息队列的消息。

  1. 直接修改消费者代码,发布灰度/蓝节点,监听 Kafka 消息
  2. 生产者改造,往 Kafka 发送消息
  3. 等待老的 Rabbit 消息消费完毕,下线,这里存在一个问题就是在进行灰度之后全量的过程中可能造成消息丢失的情况,对于这个问题的解决方案要区分来看,如果业务允许少量的丢失,那么直接全量即可,否则需要对业务做一定的改造,比如增加开关,全量之前关闭发送消息,等待存量消息消费完毕之后再全量。

优点:

  1. 基于双订阅方案改造,可以做到不同时监听两个队列的消息,减少工作量
  2. 可以做到无损迁移

缺点:同样无法保证消息有序性

实际场景问题

上述只是针对现状的迁移方案考虑,那么还有一些跟实际和复杂的问题可能需要考虑。

比如消息的场景有可能不是这种简单的发布/订阅关系,可能存在网状、环状的发布/订阅关系,该如何处理?

其实是一样的道理,只要我们能够梳理清楚每个 Exchange 之间的发布/订阅的关系,针对每个 Exchange 进行操作,就能达到一样的平滑迁移效果。

我们要做的就是针对每个 Exchange 进行迁移,而不是针对服务,否则迁移是无法进行下去的,但是这样带来的另外一个问题就是每个服务需要发布多次,而且如果碰到多个复杂消费或者生产的情况要特别小心。

实施细节

基于现状,我们对所有 Rabbit Exchange 的情况进行了详细的统计,将针对不同的 Exchange 和类型以及功能使用以下方式处理。

  1. 无用的Exchange、无生产者或者无消费者,还有没有任何流量的,可以直接删除
  2. Fanout 类型,Exchange 对应 Topic,Queue 对应 Consumer Group,还有存在使用随机队列的,需要对应多个Consumer Group(单独做一个简单的能力封装处理)
  3. Direct 类型,RoutingKey 对应 Topic,Queue 对应 Consumer Group
  4. Topic 类型,RoutingKey 对应 Topic,Queue 对应 Consumer Group,实际并未发现使用到通配符情况
  5. 延迟队列、重试等功能,基于 spring-kafka 做二次封装

验证&监控&灰度&回滚

验证

  1. 迁移后针对 Rabbit 验证,通过管理平台流量或者日志输出来确认,而且现状是大部分 Exchange 流量都比较小,所以可能需要自行发送消息验证迁移效果。
  2. 迁移后针对 Kafka 流量进行验证可以通过 Kafka Manager 平台或者日志

监控

监控通过 Kafka Manager 平台或者现有监控

灰度

方案本身 Consumer 和 Producer 都可以直接灰度发布,预发验证

回滚

服务回滚,按照发布顺序控制回退顺序

巨人的肩膀:

  1. https://xie.infoq.cn/article/bf3d9cfd01af72b326254aa81
  2. https://developer.aliyun.com/article/772095
  3. 《RabbitMQ实战指南》

大曝光!从RabbitMQ平滑迁移至Kafka架构设计方案!的更多相关文章

  1. 从RabbitMQ平滑迁移到RocketMQ技术实战

    作者:vivo 互联网中间件团队- Liu Runyun 大量业务使用消息中间件进行系统间的解耦.异步化.削峰填谷设计实现.公司内部前期基于RabbitMQ实现了一套高可用的消息中间件平台.随着业务的 ...

  2. RabbitMQ,RocketMQ,Kafka 几种消息队列的对比

    常用的几款消息队列的对比 前言 RabbitMQ 优点 缺点 RocketMQ 优点 缺点 Kafka 优点 缺点 如何选择合适的消息队列 参考 常用的几款消息队列的对比 前言 消息队列的作用: 1. ...

  3. 关于消息队列的使用----ActiveMQ,RabbitMQ,ZeroMQ,Kafka,MetaMQ,RocketMQ

    一.消息队列概述消息队列中间件是分布式系统中重要的组件,主要解决应用解耦,异步消息,流量削锋等问题,实现高性能,高可用,可伸缩和最终一致性架构.目前使用较多的消息队列有ActiveMQ,RabbitM ...

  4. RDS经典网络平滑迁移到VPC的混访方案

    专有网络VPC(Virtual Private Cloud)之间在逻辑上彻底隔离,可以使您在阿里云上构建出一个隔离的网络环境,其安全性及性能都高于经典网络,已成为云上用户首选的网络类型.为满足日益增多 ...

  5. HBase数据迁移到Kafka实战

    1.概述 在实际的应用场景中,数据存储在HBase集群中,但是由于一些特殊的原因,需要将数据从HBase迁移到Kafka.正常情况下,一般都是源数据到Kafka,再有消费者处理数据,将数据写入HBas ...

  6. RabbitMQ,RocketMQ,Kafka 消息模型对比分析

    消息模型 消息队列的演进 消息队列模型 发布订阅模型 RabbitMQ的消息模型 交换器的类型 direct topic fanout headers Kafka的消息模型 RocketMQ的消息模型 ...

  7. ActiveMQ、RabbitMQ、RocketMQ、Kafka四种消息中间件分析介绍

    ActiveMQ.RabbitMQ.RocketMQ.Kafka四种消息中间件分析介绍 我们从四种消息中间件的介绍到基本使用,以及高可用,消息重复性,消息丢失,消息顺序性能方面进行分析介绍! 一.消息 ...

  8. 《黑客大曝光》实践部分——sql注入(7/8)

    SQL注入实践 由于<黑客大曝光>中涉及到形形色色的攻击方式,从软件到硬件,甚至还有物理锁的开锁教程,当中的很多教程很有趣,但是我没有相关的环境,实践起来不好操作,比如说,查点扫描我还可以 ...

  9. 大数据平台Hive数据迁移至阿里云ODPS平台流程与问题记录

    一.背景介绍 最近几天,接到公司的一个将当前大数据平台数据全部迁移到阿里云ODPS平台上的任务.而申请的这个ODPS平台是属于政务内网的,因考虑到安全问题当前的大数据平台与阿里云ODPS的网络是不通的 ...

  10. ActiveMQ、RabbitMQ、RocketMQ、Kafka 对比(图示)

    RabbitMQ 和 Kafka 对比,一篇好的介绍文章:https://my.oschina.net/u/236698/blog/501834 ActiveMQ.RabbitMQ.RocketMQ. ...

随机推荐

  1. Promise知一二

    Promise 1.Promise的前置知识 进程(厂房) 程序的运行环境 线程(工人) 线程是实际进行运算的东西 同步 通常情况代码都是自上向下一行一行执行的 前边的代码不执行后边的代码也不会执行 ...

  2. 老板:你为什么要选择 Vue?

    大家好,我是 Kagol,Vue DevUI 开源组件库和 EditorX 富文本编辑器创建者,专注于前端组件库建设和开源社区运营. 假如你是团队的前端负责人,现在老板要拓展新业务,需要开发一个 We ...

  3. 【Shell案例】【tail/head/sed、echo $res ·· cat和管道】2、打印文件的最后5行

    描述经常查看日志的时候,会从文件的末尾往前查看,于是请你写一个 bash脚本以输出一个文本文件 nowcoder.txt中的最后5行示例:假设 nowcoder.txt 内容如下: #include& ...

  4. 【每日一题】【回溯】2021年12月29日-93. 复原 IP 地址

    有效 IP 地址 正好由四个整数(每个整数位于 0 到 255 之间组成,且不能含有前导 0),整数之间用 '.' 分隔. 例如:"0.1.2.201" 和 "192.1 ...

  5. 【大数据面试】【框架】Hadoop-入门、HDFS

    一.入门 1.常用端口号 2.x 50070:查看HDFS Web-UI 8088:查看MapReduce运行情况 19888:历史服务器 9000:hdfs客户端访问集群 50090:Seconda ...

  6. 浅谈入行Qt桌面端开发程序员-从毕业到上岗(1):当我们说到桌面端开发时,我们在谈论什么?

    谈谈我自己 大家好,我是轩先生,是一个刚入行的Qt桌面端开发程序员.我的本科是双非一本的数学专业,22年毕业,只是部分课程与计算机之间有所交叉,其实在我毕业的时候并没有想过会成为一名程序员,也没有想过 ...

  7. 解读JVM级别本地缓存Caffeine青出于蓝的要诀3 —— 讲透Caffeine的数据驱逐淘汰机制与用法

    大家好,又见面了. 本文是笔者作为掘金技术社区签约作者的身份输出的缓存专栏系列内容,将会通过系列专题,讲清楚缓存的方方面面.如果感兴趣,欢迎关注以获取后续更新. 上一篇文章中,我们聊了下Caffein ...

  8. VsCode搭建C语言运行环境以及终端乱码问题解决

    在VsCode中搭建C/C++运行环境需要先安装以下插件 1.安装c/c++插件 2.安装code runner插件 当然也可以安装一些其他的美化插件根据个人习惯,但是以上这两个是必装的. 安装好插件 ...

  9. [数据与分析可视化] D3入门教程2-在d3中构建形状

    d3.js入门教程2-在 d3.js中构建形状 文章目录 d3.js入门教程2-在 d3.js中构建形状 形状的添加 圆形的添加 矩形的添加 线段的添加 文本的添加 折线的添加 区域的添加 圆弧的添加 ...

  10. day01-ES6新特性

    ES6新特性 1.ES6是什么? DCMAScript 6.0(以下简称ES6)是JavaScript语言的下一代标准,2015年6月发布 ES6设计目标:达到JavaScript语言可以用来编写复杂 ...