本文中含有需要您注意的重要提示信息,忽略该信息可能对您的业务造成影响,请务必仔细阅读。
本文以异地应用双活架构为例,采用Msha SDK 1.5.7-SNAPSHOT版本,接入Redis、MySQL两个类型的数据库,文中提供了Spring Cloud版本的Demo供参考。更多MSHA SDK接入信息参考:同城多活MshaSDK使用手册、异地应用双活MshaSDK使用手册。
一、前提条件
准备环境:JDK8、Maven3
准备数据库:MySQL 5.7/8、Redis 6.0
准备中间件:MSE的注册中心,或者自己搭建Eureka和Nacos。
自建Eureka版本需要与Demo对应。
二、Demo示例工程
MSHA提供了基于Maven的示例工程。您可以在本地设备上编译和运行示例工程,也可以以示例工程为基础开发您的应用。
项目中添加依赖包
<dependency> <groupId>com.aliyun.msha</groupId> <artifactId>msha-router-all</artifactId> <version>${msha-sdk.version}</version> </dependency>
项目中依赖的MshaSDK包,可在MSHA控制台下载(位置:
菜单栏)msha-router-all
项目中需要手动在MySQL中创建好数据库,应用启动时会自动创建表。
三、Demo功能模块介绍及改造
1. frontend服务
1.1. 介绍
电商平台,提供视图和控制器服务。
1.2. 改造点
本云Eureka连接地址。(文件路径:frontend/src/main/resources/application.properties)
eureka.client.serviceUrl.defaultZone=http://username:password@eureka:8761/eureka/
MQ需要可以配置,不需要可以注释掉,不影响服务运行。
2. cart服务
2.1. 介绍
电商平台,提供购物车功能,数据存储在Redis中。
2.2. 改造点
项目pom.xml中添加Redis Jedis SDK。(文件路径:cartservice/cartservice-provider/pom.xml)
<dependency> <groupId>com.aliyun.unit.router</groupId> <artifactId>msha-bridge-redis-jedis</artifactId> <version>${msha-sdk.version}</version> </dependency>
本云Eureka连接地址。(文件路径:cartservice/cartservice-provider/src/main/resources/application.properties)
eureka.client.serviceUrl.defaultZone=http://username:password@eureka:8761/eureka/
Redis连接地址,primary为主库地址,standby为备库地址。(文件路径:cartservice/cartservice-provider/src/main/resources/application.properties)
spring.redis.host.primary=${REDIS_CENTER:NO_REDIS_ENV} spring.redis.host.standby=${REDIS_STANDBY:NO_REDIS_ENV} spring.redis.port=6379 spring.redis.password=${password}
添加Redis配置类(文件路径:cartservice/cartservice-provider/src/main/java/com/alibabacloud/hipstershop/cartserviceprovider/config/RedisConfig.java)
package com.alibabacloud.hipstershop.cartserviceprovider.config; import com.alibaba.fastjson.support.spring.FastJsonRedisSerializer; import com.aliyun.msha.bridge.redis.jedis.jedis.pool.MshaJedisPool; import com.aliyun.msha.bridge.redis.jedis.spring.MshaJedisConnectionFactory; import org.springframework.beans.factory.annotation.Value; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.data.redis.connection.jedis.JedisConnectionFactory; import org.springframework.data.redis.core.RedisTemplate; import redis.clients.jedis.Jedis; import redis.clients.jedis.util.Pool; import java.lang.reflect.Field; /** * @author yanshan.sy * @date 2024/02/13 */ @Configuration public class RedisConfig { @Value("${spring.redis.host.primary}") private String primaryHost; @Value("${spring.redis.host.standby}") private String standbyHost; @Value("${spring.redis.password}") private String password; @Value("${spring.redis.port}") private int port; @Bean JedisConnectionFactory jedisConnectionFactory() throws NoSuchFieldException, IllegalAccessException { Pool<Jedis> pool = new MshaJedisPool(primaryHost, port, password, standbyHost, port, password, 0); JedisConnectionFactory jedisConnectionFactory = new MshaJedisConnectionFactory(pool); Class<JedisConnectionFactory> clazz = JedisConnectionFactory.class; Field poolField = clazz.getDeclaredField("pool"); poolField.setAccessible(true); poolField.set(jedisConnectionFactory, pool); return jedisConnectionFactory; } @Bean public RedisTemplate<String, Object> redisTemplate(JedisConnectionFactory jedisConnectionFactory) { RedisTemplate<String, Object> template = new RedisTemplate<>(); template.setConnectionFactory(jedisConnectionFactory); template.setDefaultSerializer(new FastJsonRedisSerializer<>(Object.class)); return template; } }
3. checkout服务
3.1. 介绍
电商平台,提供订单信息服务,数据存储MySQL数据库中。
3.2. 改造点(文件路径:checkoutservice/checkoutservice-provider/src/main/resources/application.properties)
本云Eureka连接地址。
eureka.client.serviceUrl.defaultZone=http://username:password@eureka:8761/eureka/
MySQL连接地址
应用在spring properties文件中配置数据库连接参数,则需要在该文件进行修改。默认数据库连接地址是主云数据库地址,而在URL参数中增加另外一朵云(备云)的数据库连接地址(即备库)。
spring.datasource.url=jdbc:mysql://${主云的数据库连接地址}:3306/xxxDbName?useUnicode=true&characterEncoding=UTF-8&mshaStandbyHost=${备云的数据库连接地址}&mshaStandbyPort=3306 spring.datasource.username=username spring.datasource.password=password
应用在spring properties文件中配置JDBC Driver,则需要将原生的 com.mysql.jdbc.Driver 替换为MSHA SDK中提供Driver类com.ali.unit.router.driver.Driver。
spring.datasource.driver-class-name=com.ali.unit.router.driver.Driver
4. product服务
4.1. 介绍
电商平台,提供产品信息服务,数据存储MySQL数据库中。
4.2. 改造点(文件路径:productservice/productservice-provider/src/main/resources/application.properties)
本云Eureka连接地址。
eureka.client.serviceUrl.defaultZone=http://username:password@eureka:8761/eureka/
MySQL连接地址
应用在spring properties文件中配置数据库连接参数,则需要在该文件进行修改。默认数据库连接地址是主云数据库地址,而在URL参数中增加另外一朵云(备云)的数据库连接地址(即备库)。
spring.datasource.url=jdbc:mysql://${主云的数据库连接地址}:3306/xxxDbName?useUnicode=true&characterEncoding=UTF-8&mshaStandbyHost=${备云的数据库连接地址}&mshaStandbyPort=3306 spring.datasource.username=username spring.datasource.password=password
应用在spring properties文件中配置JDBC Driver,则需要将原生的 com.mysql.jdbc.Driver 替换为MSHA SDK中提供Driver类com.ali.unit.router.driver.Driver。
spring.datasource.driver-class-name=com.ali.unit.router.driver.Driver
5. trace服务
5.1. 介绍
电商平台,提供追踪信息服务,数据存储MySQL数据库中。
5.2. 改造点(文件路径:traceservice/src/main/resources/application.properties)
本云Eureka连接地址。
eureka.client.serviceUrl.defaultZone=http://username:password@eureka:8761/eureka/
MySQL连接地址
应用在spring properties文件中配置数据库连接参数,则需要在该文件进行修改。默认数据库连接地址是主云数据库地址,而在URL参数中增加另外一朵云(备云)的数据库连接地址(即备库)。
spring.datasource.url=jdbc:mysql://${主云的数据库连接地址}:3306/xxxDbName?useUnicode=true&characterEncoding=UTF-8&mshaStandbyHost=${备云的数据库连接地址}&mshaStandbyPort=3306 spring.datasource.username=username spring.datasource.password=password
应用在spring properties文件中配置JDBC Driver,则需要将原生的 com.mysql.jdbc.Driver 替换为MSHA SDK中提供Driver类com.ali.unit.router.driver.Driver。
spring.datasource.driver-class-name=com.ali.unit.router.driver.Driver
四、Demo运行说明
运行时需要添加环境变量
-Dregion-id=${实际的地域ID} -Dzone-id=${实际的可用区ID} -Downer-account-id=${实际的阿里云主账号ID} -Dmsha.app.name=${应用名称} -Dmsha.namespaces=${多活命名空间ID} -Dmsha.nacos.namespace=${DNCS/ACM 命名空间ID} -Dmsha.nacos.server.addr=${DNCS/ACM 连接地址}
${实际的地域ID},混合云场景(含自建IDC或非阿里云场景)需要填写,不填写的话 MSHA 根据 阿里云ECS元数据接口获取机器所属地域。
${实际的可用区ID},混合云场景(含自建IDC或非阿里云场景)需要填写,不填写的话 MSHA 根据 阿里云 ECS 元数据接口获取机器所属可用区。
${应用名称},为您实际的应用名,应用名称不支持中文。
${多活命名空间ID},可以登录MSHA管控平台,菜单栏选择
页面,列表查看已经创建好的多活命名空间ID。msha.nacos.namespace和msha.nacos.server.addr是Nacos的命名空间ID和连接地址。
添加spring.profiles.active变量使对应环境的配置生效。
例:-Dspring.profiles.active=cn-hangzhou
下载代码包,无需修改直接使用Maven编译打包,然后执行如下运行命令。
运行命令参考(注意,包含特殊字符,如&、?等,需要用引号将参数括起来)
nohup java -Dspring.profiles.active=cn-hangzhou -Dregion-id=${云regionID} -Dzone-id=${云可用区ID} -Downer-account-id=${云owner账号ID} -Dmsha.namespaces=${MSHA多活实例ID} -Dmsha.nacos.namespace=${nacos命名空间ID} -Dmsha.nacos.server.addr=${nacos连接地址} -Dmsha.app.name=productservice -jar /*/*/productservice.jar --eureka.client.serviceUrl.defaultZone="http://${username}:${password}@${eurekaURL}:8761/eureka/" --spring.datasource.username=${username} --spring.datasource.password=${password} --spring.datasource.url="jdbc:mysql://${主云的数据库连接地址}:3306/product?characterEncoding=utf8&useSSL=false&serverTimezone=GMT&mshaStandbyHost=${备云的数据库连接地址}&mshaStandbyPort=3306" -> /*/*/productservice.log 2>&1 &
如果选择EDAS部署应用,在部署时,配置中心在MSE申请并绑定到了EDAS的配置中心,那么环境变量msha.nacos.*需要填写EDAS的配置中心中分配的命名空间ID和连接地址(EndPoint)。 MSHA控制台创建
时选择【管控命令通道配置】也需要填写EDAS中分配的命名空间ID和连接地址(EndPoint)。运行成功后浏览器请求http://IP:8080访问电商平台主页。
五、接入MSHA控制台
1. 创建多活实例
异地应用双活实例新建实例。
2. 数据层配置
异地应用双活实例配置数据层,参考数据源(MySQL、Redis)录入和保护规则录入部分,数据同步链路可先不录入。
3. 主备切换测试
访问电商平台主页,确定访问的是主云数据库数据。(可以在数据库中写入标识数据)
操作主备切换异地应用双活切流,参考 部分。
没有创建数据同步链路时会报警告,测试项目,为了提高效率此处点击跳过。
主备切换完成,访问电商平台主页,确定访问的是切换后的主云(原备云)数据库数据。
测试完成后主备数据库切回。
六、问题
主备切换数据库不起作用
检查多活实例是否推送成功,MSHA控制台
推送是否成功。检查服务运行环境变量Nacos的命名空间ID和连接地址是否与MSHA控制台多活实例配置的相同。
检查多活实例连接的Nacos配置中心里是否存在数据库配置。
检查应用服务器,路径/home/admin/nacos/config/**/snapshot-tenant/**/MSHA_GROUP/下是否有数据库文件信息。
更多问题参考:常见问题
- 本页导读 (1)
- 一、前提条件
- 二、Demo示例工程
- 三、Demo功能模块介绍及改造
- 1. frontend服务
- 2. cart服务
- 3. checkout服务
- 4. product服务
- 5. trace服务
- 四、Demo运行说明
- 五、接入MSHA控制台
- 1. 创建多活实例
- 2. 数据层配置
- 3. 主备切换测试
- 六、问题