QMQ 上云方案

news2024/11/15 19:50:21

优质博文:IT-BLOG0CN

一、挑战/注意事项

【1】生产者发送消息后,QMQ国内外服务器进行了双向同步,如果消费者国内外都部署了系统,就会导致消息重复消费的问题:
目前封装了共同的SDK重构消费者的代码,生产者发送的消息中必须带有能够找到UDL的属性,根据UDL和配置的UCS策略,在消费端对消息进行过滤,从而解决重复消费的问题;

二、QMQ消息互通

默认情况下,AWS和私有云的消息是隔离的。如果业务需要可以申请AWS和私有云的消息进行互通,这样公有云的消息可以在私有云消费,同时私有云的消息可以在公有云消费,消息同步存在延迟(300-500ms)或者更长。

互通的缺陷:同步生产者发送的消息,会产生两个问题:
【1】AWS和私有云上有同名的ConsumerGroup,但每条消息都会在两边各消费一次;
【2】私有云上已经存在的ConsumerGroup,在公有云第一次部署这个消费组时,仍然会遇到消息堆积的问题,需要重置offset;

Region场景: 需要跨RegionMQ通过BaseSubject同步到中心机房Region,来保证正常业务流程。

消息处理的改造流程图如下图所示:

三、数据互通后过滤/路由方案

为了实现海内外数据隔离,需要对QMQ进行过滤,国内机房只消费境内QMQ,海外机房只消费境外QMQ
【1】消费者根据UID/是否英网订单过滤:
  ■ QMQ业务逻辑中涉及到用户行为和订单信息时,可以封装组件,QMQ生产时强制带上UID字段,并在QMQ消费入口层统一做拦截,根据UID区分是否为海外数据,实现过滤功能。前提是生产流量完全切换需要依赖UID清洗全部完成,且公共部门提供接口/规则来判断UID属于国内或国外。
  ■ QMQ中含有订单号信息时,可以在消费入口层查询订单是否属于海外数据,实现统一拦截和过滤。依赖:不需要依赖UID清洗的进度,但是需要提供机票的订单号与海内外关系的查询接口(订单详情过重性能较差,与降低压力的目标违背),且查询接口需要海内外均部署以降低响应时间。

注:是否应该专门建立一个表存储订单号,uidregion/UDL信息的映射,并按照UDL通过DRC同步至海外对应region的机房?这样查询接口才能最快速的返回结果。

可以使用SDKUCSFilteredExecutor类中的系类方法,集成UCS策略。QConfig上添加ucs_strategy_resource_idc.json配置文件,内容如下:

{
    "mqConsumeEnabledTopics": {   // 当前应用作为消费者,控制topic粒度可处理的idc;
        "bbz.oi.account.drop.deleted.orders": [
            "SIN-AWS"
        ]
    },
    "ucsStrategies": [
        {
            "strategyId": 200,  // UCS策略id,需要线下申请;strategyId对应的灰度比例:0%:232  1%:213  5%:214  10%:215  20%:216  30%:217  40%:218  50%:219  75%:220  100%:221
            "effectiveTime": "2023-03-17 10:00:00", // 是用来控制strategyId生效时间;
            "topics": [
                "bbz.oi.account.drop.deleted.orders"
            ],
            "names": [
                "xxxWorker",  // names中资源每个idc都可以执行,需要在它portal上开启;
                "yyyName"
            ]
        },
        {  // 如果同一个topic/name资源需要灰度切换,需要在ucsStrategies新增
            "strategyId": 201,
            "effectiveTime": "2023-03-17 15:00:00",
            "topics": [
                "bbz.oi.account.drop.deleted.orders"
            ]
        }
    ]
}

QMQ + UCS改造前:

@QmqConsumer(prefix = SUBJECT, consumerGroup = "xxx")
public void onMessage(Message message) throws SOAServiceException {
   process(message);
}

QMQ + UCS改造后:

@QmqConsumer(prefix = SUBJECT, consumerGroup = "xxx")
public void onMessage(Message message) throws SOAServiceException {            
    UCSFilteredExecutor.execute(this::process, message);
}

【2】QMQ框架根据地域UDL过滤: UDL - User Data Location,指用户数据所属的国家与地区,具体为用户注册时使用的国家与地区。该值用户注册后便不会发生变动。目前存在使用UID查询UDL接口。

UDL的来源包括: 1)、用户登录后操作,调用接口时会下发UIDUDL信息。2)、后台系统自动发起的操作,需要使用UID信息查询上述接口/SDK获得UDL信息。

QMQ已支持框架级别的根据UDL路由功能,即设置了UDL=SG的消息,只会在AWS-SIN被消费,不会在SH被消费了。

限制: 1)、一个QMQ消息不能包含多个UID,尤其是跨UDLUID的数据,此时无法确定需要在哪个数据中心消费。2)、目前来看,初期改造可能仍然需要靠生产者手动使用UID查询接口后设置UDL信息,且该接口似乎有白名单,不清楚后续是否会开放给业务团队使用。3)、不支持流量的灰度。

【3】生产者带tag,消费者根据tag过滤: 整体思路和方案1基本一致,但是判断逻辑移动到生产端。好处在于生产者可以复用订单数据(是否英网订单),且可以减少消费端实际消费的消息量,节约系统资源。

四、跨域幂等校验

QMQ是会将国内的QMQ消息同步到AWS上,但消息消费情况,是不会进行同步和其他特殊处理的,导致的问题是一条消息会在私有云和AWS上各消费一次,如果涉及写数据,就会产生数据冲突。

QConfig可以根据不同的region读取不同的配置文件,目前是通过配置来进行过滤。比如按照订单号的尾号进行过滤,私有云消费尾号为0-6的订单号,公有云消费尾号7-9的订单号。

问题:做灰度切换时,由于网络延迟等原因,双边的配置版本在短时间不一致,可能出现重复消费消息或者漏掉部分消息。如下图,在T3和T4两者间隔的时间,私有云在按尾号0-5过滤,而AWS在按尾号7-9过滤,而尾号为6的消息被完全丢弃掉。反之,若AWS先收到并启动新版本的配置,则会导致尾号为6的消息在两边各消费一次,可能导致后续的业务不正确。对于丢弃问题,可以尝试把丢弃通过延迟转化为重复消费问题,对于重复消费问题,采用强一致幂等的方针。对于不一致的区间,灰度流量减少的机房需要等待灰度流量增多的机房确认后,才能使新的配置生效减少流量,中间产生的重复消费,靠强制幂等来解决。

解决方案:跨域幂等,严格保证单条消息会在单边进行消费。

采用类型幂等的处理方式,跨域幂等应用的输入为MessageIDIDC机房,收到请求后会尝试将数据以SetNX写入Redis,keyMessageID,ValueIDC机房名称,若写入成功,则返回true,已经存在则判断已存在的value与请求的IDC机房是否相同,并将判断结果作为Response

跨域幂等应用部署在单边,另一个机房的应用需要跨域进行访问。

由于该问题只会在灰度配置变更后短时间内产生,所以我们可以设定一个时间,应用监听灰度配置的变化,当灰度配置发生变更后的指定时间内,才需要使用这个机制去保证幂等,过了该时间后可以直接全量消费。这样可以降低总体的处理延迟。网络通信出问题调用幂等检查失败时,需要抛出NeedRetryExceptionQMQ框架会在当前regoin内发起重试。

五、灰度依赖对DB同步的依赖

问题:生产流量逐步导入AWS时,可能是基于订单号进行灰度判断,如传入订单号,然后在订单信息中查询到对应的用户ID,然后按用户ID来判断确定在私有云还是AWS进行处理。如用户在私有云下订单,然后在AWS进行灰度判断时,可能因为数据同步的延迟,而无法获取用户ID,导致无法判断

时序信息如下 :
T1 : 私有云接收到下单请求,生成OrderID=10001的订单,订单信息写入DB
T2 : 开始DB同步,将私有云数据发向AWS
T3 : 私有云应用发送后续处理的QMQ
T4 : AWS应用接收到T3时发送的QMQ,需要对其中的订单号进行灰度判断
T5 : AWS上的DB接收到T2时的数据同步请求,将OrderID=10001的数据写入AWSDB

问题点 : T4时接收的请求中有OrderID=10001,但此时AWSDB中没有这个订单的信息,无法获取这个订单的UID信息,也就无法进行灰度判断

当前解决办法:下单时进行双写,强制将灰度判断必需的信息进行双写

时序信息如下 :
T1 : 私有云接收到下单请求,生成OrderID=10001的订单,订单信息写入DB
T2 : 私有云发起请求,将订单号和UID信息发送到AWS
T3 : AWS收到请求后,将单号和UID写入DB,并返回成功
T4 : 私有云收到AWS的应答,确认AWS上已经存储订单号和UID信息
T5 : 开始DB同步,将私有云数据发向AWS
T6 : 私有云应用发送后续处理的QMQ
T7 : AWS应用接收到T3时发送的QMQ,需要对其中的订单号进行灰度判断
T8 : AWS上的DB接收到T2时的数据同步请求,将OrderID=10001的数据写入AWSDB

重点 :T7时需要进行灰度判断时,可以直接使用T3写入的数据,保证能够获取到灰度判断必需的信息

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

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

相关文章

单片机寄存器相关知识及应用(51单片机)

在前面的STM32中我并没有直接对寄存器进行操作&#xff0c;而是通过固件库直接引用进行各个外设的配置和应用&#xff0c;现在&#xff0c;我开始进行寄存器的学习&#xff08;51单片机&#xff09;。 我们先简单看一下80C51/52的微控制头文件 <REG52.h> 一、字节寄存…

Android 提高第一次开机速度(取消系统默认手机加密)

Android刷机后第一次开机&#xff0c;系统默认是要手机加密的&#xff0c;有些机器加密就几秒钟&#xff0c;有些机器加密要30多秒甚至更长&#xff0c;严重影响了开机速度。 修改路径&#xff1a; device/qcom/xxxx/fstab_AB_variant.qcom 有一些是这个文件&#xff1a; devic…

补:在Spring Boot 当中使用 Thymeleaf 视图解析器

补&#xff1a;在Spring Boot 当中使用 Thymeleaf 视图解析器 想要在 Spring Boot 当中使用 Thymeleaf 视图&#xff0c;就需要导入相关的 jar 依赖。在 pom.xml 文件中配置 。 <!-- 引入 thymeleaf-start ,项目会自动完成配置&#xff0c;--><dependency>…

MPU6050移植DMP读出三轴角度

先决条件 MPU6050移植完成&#xff0c;能够正确读出加速度和陀螺仪原始数据 DMP移植 官方包代码复制 解压demo&#xff0c;打开motion_driver_6.12\arm\STM32F4_MD6\Projects\eMD6\core\driver&#xff0c;复制路径下的eMPL到自己工程 代码移植 需要修改的有三个文件&am…

GD32/STM32启动过程

GD32/STM32启动过程 文章目录 GD32/STM32启动过程前言一、系统架构二、自举配置三、启动文件四、启动流程总结 前言 本文以STM32F407为例简单介绍其启动过程。 提示&#xff1a;以下是本篇文章正文内容&#xff0c;下面案例可供参考 一、系统架构 STM32F407的系统架构如图所…

libyuv之linux编译

文章目录 一、下载源码二、编译源码三、注意事项1、银河麒麟系统&#xff08;aarch64&#xff09;&#xff08;1&#xff09;解决 armv8-adotprodi8mm 指令集支持问题&#xff08;2&#xff09;解决 armv9-asve2 指令集支持问题 一、下载源码 到GitHub网站下载https://github.…

【JAVA】Undertow的使用及性能优化,以及Undertow与Tomcat的对比

文章目录 Undertow优势Undertow使用Undertow性能优化线程池配置缓冲区和内存使用连接和请求超时禁用无关的设置编程式配置启用HTTP/2 Undertow与Tomcat的对比 更多相关内容可查看 当你进行Tomcat调优发现在怎么调都无法满足需求的时候&#xff0c;Undertow容器在性能和内存上都…

盘点2024年大家都在用的短视频剪辑工具

你现在休息的时间是不是都靠短视频来消遣&#xff1f;看着看着你就会发现短视频制作好像我也可以了吧&#xff1f;这次我就介绍一些简单好操作的短视频剪辑工具。 1.FOXIT视频剪辑 连接直达>>https://www.pdf365.cn/foxitclip/ 短视频剪辑其实也不难&#xff0c;只需…

MySql-表的内外连接

文章目录 前言一、内连接二、外连接1.左外连接2.右外连接 前言 表的内外连接跟我们上节课讲的笛卡尔积很相似。 一、内连接 格式&#xff1a;select 字段 from 表1 inner join 表2 on 连接条件 and 其他条件&#xff1b; 例如&#xff1a;显示SMITH的名字和部门名称 二、外…

RB-SQL:利用检索LLM框架处理大型数据库和复杂多表查询的NL2SQL

NL2SQL的任务是将自然语言问题转换为SQL查询&#xff0c;以便从数据库中获取答案。现有LLM来指导SQL生成的方法在处理大型数据库和复杂多表查询时存在挑战&#xff0c;尤其是在处理冗余信息和提高提示工程效率方面。 (a) 利用大型语言模型&#xff08;LLM&#xff09;解决文本…

ctfshow-web入门-sql注入(web249-web253)nosql 注入

目录 1、web249 2、web250 3、web251 4、wen252 5、web253 1、web249 开始nosql,flag在flag中 $user $memcache->get($id); 使用 Memcache 类的 get 方法从缓存中获取数据&#xff0c;$id 是传入的键&#xff0c;用于从缓存中获取与该键对应的值&#xff0c;结果存储…

明基相机sd卡格式化还能恢复数据吗?可以这样操作

随着数字摄影的普及&#xff0c;相机SD卡已成为我们记录生活点滴的重要载体。然而&#xff0c;不小心将SD卡格式化&#xff0c;导致珍贵照片和视频瞬间消失&#xff0c;无疑是摄影爱好者的一大噩梦。面对这样的突发情况&#xff0c;许多朋友可能会感到无助与绝望。但实际上&…

【计算机组成原理】概述+数制与编码

目录 计算机组成原理概述计算机基本组成计算机系统的层次结构计算机性能指标 数制与编码进位计数制及其相互转换数据的编码与表示校验码 计算机组成原理概述 计算机基本组成 运算器、控制器、存储器、输入输出设备 运算器&#xff1a;完成数据的暂存、变换、算术运算和逻辑…

OpenCV结构分析与形状描述符(23)确定一个点是否位于多边形内的函数pointPolygonTest()的使用

操作系统&#xff1a;ubuntu22.04 OpenCV版本&#xff1a;OpenCV4.9 IDE:Visual Studio Code 编程语言&#xff1a;C11 算法描述 进行点在轮廓内的测试。 该函数确定点是在轮廓内、轮廓外&#xff0c;还是位于一条边上&#xff08;或与顶点重合&#xff09;。它返回正值&…

【可变参模板】基类参数包的展开

一、基类参数包的展开 1.1基类参数包的展开 C C C是一个支持多继承的语言&#xff0c;因此继承的类也可以是一个基类的参数包 注意继承的语法是 p u b l i c : c l a s s . . . public: class ... public:class...&#xff0c;需要补充 . . . ... ...作为基类参数包的标志。…

Linux 驱动编写框架 并编译导入开发板

向内核新加文件&#xff1a;例如 demo1.c 1. 创建并编辑新的文件 #include <linux/init.h> #include <linux/kernel.h> #include <linux/types.h> #include <linux/fs.h> #include <linux/module.h> #include <linux/kdev_t.h> #include …

Qt控制开发板的LED

Qt控制开发板的LED 使用开发板的IO接口进行控制是嵌入式中非常重要的一点&#xff0c;就像冯诺依曼原理说的一样&#xff0c;一个计算机最起码要有输入输出吧&#xff0c;我们有了信息的接收和处理&#xff0c;那我们就要有输出。 我们在开发板上一般都是使用开发板的GPIO接口…

vue3使用provide和inject传递异步请求数据子组件接收不到

前言 一般接口返回的格式是数组或对象&#xff0c;使用reactive定义共享变量 父组件传递 const data reactive([])// 使用settimout模拟接口返回 setTimeout(() > {// 将接口返回的数据赋值给变量Object.assign(data, [{ id: 10000 }]) }, 3000);provide(shareData, dat…

02请求响应(简单参数)

一、操作目的 前端通过post/get请求&#xff0c;传递给后端简单的数据&#xff0c;后端接收后在控制台打印出来&#xff0c;并将结果返回给前端页面展示出来。&#xff08;这里我们用postman来模拟前端页面&#xff0c;而非真实的通过编写前端代码&#xff0c;通过浏览器来展示…

Docker数据挂载本地目录

docker内的数据映射可以不通过数据卷&#xff0c;直接映射到本地的目录。下面将以mysql容器示例&#xff0c;完成容器的数据映射。 注意&#xff1a;每一个不同的镜像&#xff0c;将来创建容器后内部有哪些目录可以挂载&#xff0c;可以参考DockerHubDocker Hub Container Ima…