当前位置: 首页 > 科技观察

MQ如何在高速飞机上换发动机时实现平滑迁移?

时间:2023-03-12 22:56:27 科技观察

前几天,杨紫琼在知识星球上提问,说公司要切换MQ,从老服务商升级到新服务商,问有什么好的解决办法。这个需求估计挺常见的,这里分享一些经验。一、MQ架构简述如上图所示,使用MQ异步通信一般分为三层:消息发送方:使用MQ客户端产生消息。MQ客户端::SendMsg(主题,消息);MQ服务:传递消息。消息接收者:使用MQ客户端消费消息。MQ客户端::RecvMsg(主题、消息、CALLBACK_FUNC);这是一个典型的发布-订阅架构。如果要更换MQ供应商,至少需要更换三个地方:sendermq-clientMQ-serverreceivermq-如何平滑的迁移client是今天要讨论的话题。2.平滑迁移方案平滑迁移的目标是:服务不中断,平滑升级。如果主题很多,需要一个一个迁移。每个主题的迁移分为三个步骤。第一步:消费者端的双向订阅如上图所示。可以假设:粉色是老MQ系统,蓝色是新MQ系统平滑迁移的最终目标。第一步是升级消费者。对于同一个主题,您必须同时订阅旧MQ和新MQ。此时虽然“NewService-NewSubscription”之间有TCP连接,但是“NewPublish”不在线,实际上不会发送任何消息(上图中的虚线),消息还是经过旧MQ(真正的Wire)。第2步:生产者升级到新版本。第二步升级producer,由旧MQ发布,升级到新MQ版本。此时会在“新发布-新服务-新订阅”之间建立TCP连接,将消息传递到新的通道(上图中的实线)。虽然“旧服务-旧订阅”之间存在TCP连接,但实际上并不会发送消息(上图中的虚线)。第3步:消费者使用旧订阅下线。第三步,升级消费者,离线登录旧订阅。整个MQ迁移完成。3、架构启发MQ改变服务商,蚂蚁搬家,一步步平滑迁移。成本实际上是相当高的。之所以这么麻烦,不能统一升级,本质上是业务和底层基础设施细节的耦合(也就是用哪个MQ)。如果公司在规划前期的技术体系时能够“浅封装一层”,就可以隔离“??业务代码”和“底层基础设施细节”。让我们举一个更常见的例子。如果没有封装层,业务代码为:ActiveMQ-client::SendMsg(topic,msg);ActiveMQ-client::RecvMsg(topic,msg,CALLBACK_FUNC);即业务方需要关心ActiveMQ,如果基础设施升级为RabbitMQ,业务代码也需要升级。如果是浅层封装:ShenJianMQ::SendMsg(topic,msg){ActiveMQ-client::SendMsg(topic,msg);}ShenJianMQ::RecvMsg(topic,msg,CALLBACK_FUNC)ActiveMQ-client::RecvMsg(topic,msg,CALLBACK_FUNC);}业务端不需要关心MQ底层,只需要依赖ShenJianMQ这个基础组件。此时如果基础设施升级为RabbitMQ,只需要升级基础组件ShenJianMQ。第一步:RecvMsg升级为双向订阅。ShenJianMQ::RecvMsg(topic,msg,CALLBACK_FUNC)ActiveMQ-client::RecvMsg(topic,msg,CALLBACK_FUNC);RabbitMQ-client::RecvMsg(topic,msg,CALLBACK_FUNC);}第二步:SendMsg升级到新版本.ShenJianMQ::SendMsg(topic,msg){RabbitMQ-client::SendMsg(topic,msg);}第三步:RecvMsg离线老订阅。ShenJianMQ::RecvMsg(topic,msg,CALLBACK_FUNC)RabbitMQ-client::RecvMsg(topic,msg,CALLBACK_FUNC);}你会发现,除了升级和依赖新版本的ShenJianMQ基础组件外,业务代码确实不需要修改代码。不仅是MQ、缓存和数据库客户端,一层浅层封装也可以实现业务代码和基础组件的解耦。更换基础组件或升级基础组件时,业务代码无需升级。画外音:经过一层浅层封装,监控/告警/数据采集等任务更容易统一实现。关于MQ平滑迁移的问题,先说这么多,希望能回答杨??紫琼的问题。【本文为专栏作者《58神剑》原创稿件,转载请联系原作者】点此阅读更多该作者好文