背景信息
数据双活架构
数据双活架构采用基于业务数据分片的单元化模式,不受数据中心距离限制,流量在单元内闭环,单元故障影响不外溢。
相比基于数据主备模式的应用双活架构业务体验更好、故障爆炸半径更小、容灾切换更平滑,但应用改造成本更高,要求业务数据拆分、流量带标和标记传递。
架构示意如图:
推荐业务场景:
- 单个中心数据负载过高,需要水平拆分(要求业务数据能够拆分)。
- 数据中心距离较远,异地调用成本过高。
- 技术投入和技术栈能够支撑应用改造。
示例应用架构
示例业务应用由下列微服务共同组成,依赖关系如下图箭头所示。
- lilishop-front:MVC服务,负责和用户交互。
- lilishop-goods:商品应用,提供商品、库存服务。
- lilishop-cart:购物车应用,提供购物车添加、存储和查询服务。
- lilishop-order:订单应用,提供下单、物流、订单查询服务。
采用SpringBoot技术栈,RPC框架为Dubbo,使用Nacos作为注册中心,数据库使用MySQL。
接入步骤
1、准备好资源、环境与应用
1.1、资源开通
应用容灾多活是构建在已有应用之上的管控,协同其他云产品,但不负责其他云产品的生命周期,需要您提前规划与创建。
您可以根据规划的物理架构,在指定区域或可用区提前开通与创建应用部署所需的资源与服务,例如虚拟私有云VPC、微服务云应用平台MSAP和弹性云主机ECS等。
1.2、网络互通
数据双活架构可能存在跨数据中心调用的场景,需要您提前打通两个数据中心之间的网络。
您可以根据选定的物理架构,选择合适粒度的网络连通方案,例如连通两个区域的云间高速产品和连通两个VPC的对等连接产品等。
1.3、应用准备
在这个示例中,对应用的部署方式没有强制要求,可以开通弹性云主机ECS实例自行部署应用服务,也可以开通微服务云应用平台MSAP进行应用部署管理,本示例使用微服务云应用平台MSAP 。
还需要您开通:
- 关系型数据库MySQL版实例,并结合数据传输服务DTS进行业务数据跨中心同步。
- 微服务引擎注册配置中心用于注册中心和管控通道。
- 微服务引擎云原生网关用于前端服务转发。
本示例将以上应用进行单元化改造,改造后云上部署架构如下。
图 部署架构
2、开通应用容灾多活服务,创建多活应用系统
2.1、创建应用
- 登录应用高可用控制台,单击左侧菜单栏应用容灾多活,在应用容灾多活菜单下单击数据双活。
- 进入数据双活管理页面,然后单击创建应用系统,输入lilishop商城系统,勾选应用系统需要开通的模块(微服务引擎注册配置中心、微服务引擎云原生网关、Dubbo、关系数据库MySQL版)、勾选“我已阅读,理解并接受《应用容灾多活计费规则》”,单击确定按钮完成创建。
2.2、架构管理
2.2.1、单元配置
- 在应用容灾多活菜单下单击数据双活, 在应用系统列表页面,单击lilishop商城系统, 进入应用系统概览页面。
- 单击左侧菜单栏系统架构配置,单击站点管理的创建按钮,依次创建广州站点和北京站点。
- 单击左侧菜单栏系统架构配置,单击单元管理的创建按钮,依次创建广州单元和北京单元。
2.2.2、路由配置
- 在应用容灾多活菜单下单击数据双活,在应用系统列表页面,单击lilishop商城系统,进入应用系统概览页面。
- 单击左侧菜单栏路由规则配置,单击创建,依次创建四个单元组,前端模块,商品模块、购物车模块和订单模块。
- 解析规则支持header和parameter的排列组合方式,本示例先从HTTP#header中查找,如未命中再从DUBBO#parameter第一个参数中提取userId。
2.3、资源管理
2.3.1、接入层配置
- 在应用容灾多活菜单下单击数据双活,在应用系统列表页面,单击lilishop商城系统,进入应用系统概览页面。
- 单击左侧导航栏容灾配置,在容灾配置菜单下单击接入层配置,进入容灾配置-接入层配置页面。
- 在站点网关列表,单击所选站点操作列选择网关按钮,弹出接入层网关选择页面。在接入层网关实例列表,单击所选网关实例操作列选择按钮,选择已开通的网关实例,完成站点网关实例绑定。
- 单击URI配置列表上方创建按钮,弹出新增URI配置页面,依次填入各个单元组URI、应用入口地址等信息完成配置。
2.3.2、数据层配置
- 在应用容灾多活菜单下单击数据双活,在应用系统列表页面,单击lilishop商城系统, 进入应用系统概览页面。
- 单击左侧导航栏容灾配置,在容灾配置菜单下单击数据层配置,进入容灾配置-数据层配置页面。
- 单击数据源配置列表上方创建按钮,依次创建各个单元组不同站点的数据源。
- 单击数据同步任务列表上方创建按钮,以创建数据同步任务。
- 选择创建的同步任务,点击配置链路,弹出配置数据同步链路页面,在配置数据同步链路页面点击绑定,弹出绑定同步链路信息页面。
- 在绑定同步链路信息页面依次选择同步工具实例并根据需求选择关联方式,在本示例中选择创建任务,进一步填写需要同步的库表配置和同步配置,完成所有必要信息填写后,点击确定保存配置。
- 在数据同步任务列表页面,找到刚刚创建的任务,选择创建的任务,点击批量启动按钮,开启同步。
- 若同步任务的服务状态为全量同步中或增量同步中,则说明开启同步成功。
2.3.3、基线推送
- 在应用容灾多活菜单下单击数据双活,在应用系统列表页面,单击lilishop商城系统,进入应用系统概览页面。
- 在左侧导航栏选择容灾配置,在容灾配置菜单下单击总览,在总览页面单击基础配置推送按钮进入基础配置推送列表页面。
- 在基础配置推送列表页面,点击左侧推送配置按钮,查看任务下方各个单元组配置变更内容,确认无误后,输入任务名称。
- 单击确定按钮,自动跳转到基础配置推送任务列表页面,选择刚刚创建的任务名称,点击状态列,可以查看任务的各个步骤详情以及任务进度。
- 在任务处理结果列,点击任务结果,可以查看任务详情信息。
3、改造数据面
3.1 表主键改造
需要确保应用数据所有主键全局唯一,推荐使用UUID或者雪花ID,以避免数据在跨地域双向同步中产生写入冲突。
本示例以雪花ID为例做改造,如下:
@ApiModelProperty(value = "购物车表ID")
@TableId(value = "id", type = IdType.ASSIGN_ID)
private Long id;
...
@Configuration
public class MyBatisPlusConfig {
@Bean
public IdentifierGenerator identifierGenerator() {
return new SnowflakeIdGenerator();
}
}
3.2、服务注入改造
部分RPC框架支持优先本地调用策略,可能与单元化路由纠错相冲突,需要进行改造。
以Dubbo为例,需要在DubboReference和Reference中将injvm参数设置为false,示例代码如下:
...
@DubboReference(injvm = false)
private CrmebStoreCartService storeCartService;
...
@Reference(injvm = false)
private CrmebOrderService orderService;
...
3.3、路由标透传改造
应用在单元组设置DUBBO服务的路由标时,可以设置路由标从方法参数或请求上下文中取值。
本示例以通过参数传递方式,配置第一个参数为路由标,代码如下:
@DubboReference(injvm = false)
private CrmebStoreCartService storeCartService;
...
/**
* 修改商品数量
*
* @param id
* @param number 修改的产品数量
*/
@ApiOperation(value="修改") @RequestMapping(value="/num", method=RequestMethod.POST) public CommonResult<String>update(@RequestParam Long id, @RequestParam Integer number) {
// 传递用户id
if (storeCartService.updateCartNum(UserContext.currentUser().getId(), id, number)) {
return CommonResult.success();
} else {
return CommonResult.failed();
}
}
3.4、定时任务改造
在数据双活架构下,定时任务本身可能无法根据路由规则进行调度,可以通过数据过滤的方式让每个单元的任务只处理本单元的数据。
首先引入多活SDK:
...
<dependency>
<groupId>com.ctg.amss</groupId>
<artifactId>amss-agent</artifactId>
<version>${版本号}</version>
</dependency>
...
其次在处理数据前增加数据归属判断:
...
// 获取需要处理的数据
List<User> businessData = new ArraList<>();
...
for (Object data : businessData) {
// 从数据中提取路由标
String routerId = data.getTenantId();
// 计算路由命中
if (AmssAgentManager.sdk().isInLocalUnit(routerId)) {
// 执行任务
}
}
...
4、应用接入
4.1、 应用安装探针
- 登录应用高可用控制台。
- 单击左侧菜单栏应用容灾多活,在应用容灾多活菜单下单击数据双活,进入数据双活管理页面。
- 在应用系统列表中找到需要配置的应用系统,单击应用系统名称,进入应用系统概览页面。
- 单击左侧导航栏容灾配置,在容灾配置菜单下单击服务层配置,进入容灾配置-服务层配置页面。
- 在弹出应用接入页面,点击查看密钥,获取密钥。
- 为应用配置JVM参数,根据应用所属单元组和单元,将参数模板中的各个变量替换为实际的值。
-javaagent:${探针JAR所在路径}
-Damss.application.group=${单元组编码}
-Damss.application.name=${应用名称}
-Damss.service.ip=${应用IP,可选}
-Damss.commander.servers=${管控通道地址}
-Damss.commander.secret=${管控通道密钥}
配置参数说明:
- ${管控通道地址}:您可以在应用容灾多活控制台的应用接入页面查看管控通道地址。
- ${管控通道密钥}:您可以在应用容灾多活控制台的应用接入页面点击管控通道密钥。
您需要根据实际参数为每个应用配置JVM启动参数,应用通过JavaAgent的方式植入管控逻辑,将应用纳入应用容灾多活系统。
启动脚本示例如下:
- 前端模块广州站点启动脚本
-javaagent:/app/mall/agent/amss-agent-${版本号}.jar
-Damss.application.name=lilishop_front
-Damss.application.group=front
-Damss.command.servers=###
-Damss.command.secret=###
- 前端模块北京站点启动脚本
-javaagent:/app/mall/agent/amss-agent-${版本号}.jar
-Damss.application.name=lilishop_front
-Damss.application.group=front
-Damss.command.servers=###
-Damss.command.secret=###
4.2、重启应用
安装了探针的应用在启动时,会自动上报心跳信息。在控制台服务层配置页面,若该应用实例信息显示在列表中且状态列为在线,则说明探针安装成功。
4.3、开启注册配置中心服务同步
- 登录注册配置中心控制台,选择本应用所使用的注册中心Nacos实例,点击实例ID,进入实例详情页面。
- 在左侧导航栏选择迁移上云,在迁移上云菜单下点击概览查看同步工具状态。
- 若未安装,点击安装按钮进行安装。
- 若已安装,选择迁移集群管理,点击新增集群,填写跨站点注册中心所属集群名称、命名空间、用户名、密码和连接地址信息。
- 选择同步任务管理,点击新增任务,填写任务名称、源集群、目标命名空间,选择所有需要同步的服务。
- 在左侧导航栏选择服务管理,点击服务列表,查看注册命名空间下的服务数量由1变成2,代表服务同步开启成功。
5、功能验证
5.1、验证流量分发能力
验证 | 说明 |
---|---|
测试内容 | 验证网关流量分发。 |
测试类型 | 人工UAT测试。 |
前提条件 | - 完成微服务引擎云原生网关组件的订购。 - 登录云原生网关控制台,选择该应用的云原生网关实例,点击功能设置中可观测性配置,启用链路追踪功能。 - 在应用控容灾多活制台完成网关配置。 |
测试步骤 | 1. 根据流量比例规则,查看网关转发是否正常。例如,初始化时北京单元、广州单元的流量比例为0:100。 2. 登录lilishop商城系统首页,在云原生网关控制台查看链路追踪,请求始终访问到广州单元入口。 3. 登录lilishop商城系统进行添加购物车和下订单操作,在云原生网关控制台查看链路追踪,请求始终访问到广州单元入口。 |
测试结果 | 符合预期。 |
5.2、验证双向同步能力
验证 | 说明 |
---|---|
测试内容 | 验证双向同步能力。 |
测试类型 | 人工UAT测试。 |
前提条件 | - 应用挂载上应用容灾多活探针。 - 完成微服务引擎云原生网关组件的订购。 - 登录云原生网关控制台,选择该应用的云原生网关实例,点击功能设置中可观测性配置,启用链路追踪功能。 - 在应用控容灾多活制台完成接入层配置。 - 在应用容灾多活控制台完成数据层配置。 |
测试步骤 | 1. 准备账号A和B,配置精确路由规则,通过网关链路追踪功能,确认A和B的请求分别落到北京和广州单元。 2. 暂停数据同步任务,A和B分别进行添加购物车操作,确认A和B的购物车数据分别存储到北京和广州数据源。 3. 启动数据同步任务,等待数据追平,确认A和B的购物车数据均存储到两个数据源。 4. 发起路由切换任务,将A和B的请求分别调整到不同单元。 5. 切换成功后,通过网关链路追踪功能,确认A和B的请求已到不同单元,并能正常查看前述购物车信息。 6. A和B进行购物车修改操作,确认购物车数据正常存储到两个数据源。 7. 重复步骤4-6,确认流量多次轮换不影响数据存储。 |
测试结果 | 符合预期。 |
5.3、验证数据保护能力
验证 | 说明 |
---|---|
测试内容 | 验证数据保护能力。 |
测试类型 | 人工UAT测试。 |
前提条件 | - 应用挂载上应用容灾多活探针。 |
测试步骤 | 1. 初始化配置北京单元、广州单元的流量比例为0:100。 2. 跳过接入层,直接访问北京订单服务进行下单操作,提示操作失败。 3. 查看探针日志,确认数据层将请求拦截。 4. 发起切流任务,调整北京单元、广州单元的流量比例为100:0。 5. 跳过接入层,直接访问北京订单服务进行下单操作,提示操作成功。 |
测试结果 | 符合预期。 |