TSF Consul 迁移方案

最近更新时间:2025-01-25 16:52:42

我的收藏

操作场景

当您在生产环境上已经使用了腾讯云的 TSF Consul 集群作为服务治理中心,并希望将其上已运行的服务迁移至腾讯云的北极星网格时,可以根据您的业务需求,在本指引中选择适合您的迁移方案。
本文主要介绍 TSF Consul 迁移的方案和操作步骤,帮助您的微服务应用的服务治理将 TSF Consul 集群迁移到北极星网格集群。

前提条件

已创建 PolarisMesh 北极星网格,请参见 创建 PolarisMesh 治理中心
本地编译构建打包机器环境已安装了Java JDK、Maven,并且能够访问 Maven 中央库。

迁移改造

应用侧改造

依赖更新

您需要将 TSF Consul 对应的 SDK Spring Cloud TSF 升级为 Spring Cloud Tencent(后称 SCT )。因为 Spring Cloud TSF 在依赖管理中推荐以其自身为parent,而 SCT 的定位是治理组件,给用户的服务调用组件提供服务治理功能,但不包含服务调用实际的组件,因此需要用户额外引入服务调用等其他组件。
以 Spring Cloud TSF 2021版本为例。业务代码项目父依赖更新为如下所示,该父 pom 指定了:
spring-boot-starter-parent,开源 Spring Boot 的 版本号为2.7.18。
spring-cloud-tencent-dependencies,开源 SCT 的版本号为2.0.0.0-2021.0.9。
spring-cloud-dependencies,开源 Spring Cloud 的版本号为2021.0.9。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<!-- Spring Boot Parent -->
<parent>
<artifactId>spring-boot-starter-parent</artifactId>
<groupId>org.springframework.boot</groupId>
<version>2.7.18</version>
</parent>

<groupId>com.tencent.tsf</groupId>
<artifactId>tsf-demo</artifactId>
<version>1.0.0</version>
<packaging>pom</packaging>

<modules>
<module>provider-demo</module>
<module>consumer-demo</module>
</modules>

<properties>
<!-- Spring Cloud Tencent -->
<revision>2.0.0.0-2021.0.9</revision>
<!-- Spring Cloud -->
<spring.cloud.version>2021.0.9</spring.cloud.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
</properties>

<dependencyManagement>
<dependencies>
<!-- Spring Cloud Tencent Dependencies -->
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-tencent-dependencies</artifactId>
<version>${revision}</version>
<type>pom</type>
<scope>import</scope>
</dependency>

<!-- Spring Cloud Dependencies -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring.cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>

<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
业务代码项目子依赖更新可以参考下方 pom.xml ,该 pom 引入了如下依赖:
spring-cloud-starter-tencent-all,SCT 服务治理组件总包。
spring-boot-starter-web,web应用组件,提供 HTTP 服务给外部调用。
spring-cloud-starter-openfeign,支持应用使用 Feign 客户端调用其他服务。如果不使用 Feign 客户端,也可以不引入。
spring-cloud-starter-bootstrap,支持应用使用 bootstrap.xml 或者 bootstrap.yaml 或者 bootstrap.yml 作为配置文件。Spring Cloud 2021 以前的版本默认引入改依赖,Spring Cloud 2021 开始不默认引入,因此需要手动引入。或改为 application.xml 或者 application.yaml 或者 application.yml 。
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>

<parent>
<groupId>com.tencent.tsf</groupId>
<artifactId>tsf-demo</artifactId>
<version>1.0.0</version>
</parent>

<artifactId>consumer-demo</artifactId>
<packaging>jar</packaging>
<name>consumer-demo</name>

<dependencies>
<!-- Spring Cloud Tencent 服务治理组件 -->
<dependency>
<groupId>com.tencent.cloud</groupId>
<artifactId>spring-cloud-starter-tencent-all</artifactId>
</dependency>

<!-- web应用组件,提供 HTTP 服务给外部调用 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>

<!-- 支持应用使用 Feign 客户端调用其他服务。如果不使用 Feign 客户端,也可以不引入 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>

<!-- 开启 Bootstrap 阶段 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-bootstrap</artifactId>
</dependency>
</dependencies>
</project>

配置更新

SCT 使用了全新的配置,完整配置及其说明如下所示。
server:
port: 48082 # 端口号
spring:
application:
name: QuickstartCallerService # 服务名
config:
import: optional:polaris # 开启北极星的配置中心
cloud:
polaris:
address: grpc://{北极星的ip}:8091 # 北极星的治理中心地址
namespace: default # 服务的命名空间,默认default
enabled: true # 开启北极星服务治理功能
discovery:
enabled: true # 开启北极星服务发现,默认true
register: true # 开启北极星服务注册,默认true
heartbeat:
enabled: true # 开启北极星心跳,默认true
heartbeat-interval: 5 # 心跳间隔,默认5(秒)
health-check-url: /quickstart/caller/healthCheck # 心跳前接口检测,默认为空
zero-protection:
enabled: true # 开启北极星服务发现零实例保护,默认为false
is-need-test-connectivity: true # 开启北极星服务发现零实例保护连通性测试,默认为false
instance-id: QuickstartCallerService-0 # 指定服务注册的实例ID,默认为注册后服务端返回值
token: NO_TOKEN # 指定连接北极星的TOKEN,默认为空
weight: 100 # 指定该服务被调用时的权重,默认为100
version: 2.0.0.0 # 指定该服务注册时的版本号,默认为1.0.0
protocol: HTTP # 指定该服务的对外提供服务协议,默认为HTTP
service-list-refresh-interval: 60000 # 指定服务列表刷新间隔,默认为60000(毫秒)
eager-load:
enabled: true # 服务发现预热功能总开关,默认为false
feign:
enabled: true # Feign 服务发现预热开关,默认为true
config:
address: grpc://{北极星的ip}:8093 # 北极星的配置中心地址
port: 8093 # 北极星的配置中心端口,默认为8093
auto-refresh: true # 开启北极星配置自动刷新,默认为true
refresh-type: reflect # 指定北极星配置刷新机制,默认为refresh_context,可选reflect、refresh_context
data-source: polaris # 指定配置来源,默认为polaris
groups:
- name: ${spring.application.name} # 指定北极星配置分组名
files: [ "config/caller.properties" ] # 指定北极星配置文件名列表
enabled: true # 开启北极星配置中心功能
token: NO_TOKEN # 指定连接北极星的TOKEN,默认为空
shutdown-if-connect-to-config-server-failed: true # 开启配置中心连接快速失败,默认为true
local-file-root-path: ./polaris/backup/config # 指定本地配置
internal-enabled: true # 开启内部配置文件拉取,默认为true
connect-remote-server: true # 是否连接远端配置中心,默认为true
crypto:
enabled: true # 开启配置加密,默认为true
loadbalancer:
strategy: roundRobin # 负载均衡策略,默认为polarisWeightedRoundRobin,可选roundRobin、random、polarisWeightedRandom、polarisRingHash、polarisWeightedRoundRobin
contract:
enabled: true # 开启服务契约,默认为true
exposure: true # 开启服务契约接口,默认为true
report:
enabled: true # 开启服务契约上报,默认为true
base-package: com.tencent.cloud # 指定服务契约扫描的基础路径
exclude-path: /echo # 排除以下路径的服务契约扫描,逗号分隔
group: polaris # 指定服务契约分组,默认为polaris
base-path: /** # 扫描以下路径的服务契约,逗号分隔,默认为/**
name: Polaris # 服务契约名称,默认为服务名
circuitbreaker:
enabled: true # 开启服务熔断功能,默认为true
ratelimit:
enabled: true # 开启服务限流功能,默认为true
reject-http-code: 429 # 服务限流时的返回码,默认为429
reject-request-tips: ratelimited # 服务限流时的返回字段
rejectRequestTipsFilePath: reject-tips.html # 服务限流时的返回HTML
maxQueuingTime: 1000 # 匀速排队限流的最大排队时间,默认为1000(毫秒)
router:
enabled: true # 开启服务路由功能,默认为true
metadata-router:
enabled: true # 开启元数据路由,默认为true
namespace-router:
enabled: true # 开启命名空间路由,默认为false
fail-over: all # 命名空间路由降级配置,默认为all,可选none
nearby-router:
enabled: true # 开启就近访问,默认为false
match-level: ZONE # 指定最低就近级别,默认为ZONE,可选CAMPUS、ZONE、REGION
rule-router:
enabled: true # 开启规则路由,默认为true
fail-over: all # 规则路由降级配置,默认为all,可选none
admin:
port: 28083 # 管理端口,默认为28080
stat:
enabled: true # 开启监控,默认为true
path: /metrics # Prometheus的path,默认为/metrics
pushgateway:
enabled: true # 开启pushgateway模式,默认为false
address: {北极星的ip}:9091 # 指定pushgateway地址
push-interval: 30000 # 指定pushgateway间隔,默认为30000(毫秒)
lossless:
enabled: false # 开启优雅上下线,默认为false
health-check-path: /health # 健康检查路径
delay-register-interval: 30000 # 延迟上线时间,默认为30000(毫秒)
health-check-interval: 1000 # 健康检查间隔,默认为1000(毫秒)
local-ip-address: 127.0.0.1 # 指定注册ip
local-port: 48082 # 指定注册端口号
logging:
path: ./polaris/logs # 指定北极星日志路径
tencent:
metadata:
content:
transk: transv # 指定服务实例元数据
dispk: dispv
region: huanan
zone: shenzhen
campus: shenzhen-1
transitive:
- tranv # 指定传递元数据的key列表
disposable:
- dispk # 指定单跳元数据的key列表
headers:
- headerk # 指定原始头部传递的key列表
rpc-enhancement:
enabled: true # 开启调用增强组件,默认为true
reporter:
enabled: true # 开启服务调用上报
ignore-internal-server-error: true # 是否忽略500,默认为true
series: server_error # 指定服务错误的HTTP系列码,默认为server_error(5xx)
statuses: gateway_timeout, bad_gateway, service_unavailable # 指定服务错误的HTTP错误码
management:
endpoints:
web:
exposure:
include:
- polarisdiscovery # 开启服务注册发现端点
- polariscircuitbreaker # 开启服务熔断端点
- polarisconfig # 开启动态配置端点
- polarisroute # 开启服务路由端点
- polarisratelimit # 开启服务限流端点
- polarismetadata # 开启服务元数据端点

代码改造

删除 Spring Cloud TSF 注解(可选)
以下注解为 Spring Cloud TSF 定义的功能注解,SCT 做了兼容化处理,无需引入注解也可开启对应功能,或通过配置进行关闭,引入注解不会报错。
@EnableTsfUnit // 新单元化单独开启
@EnableTsfAuth // 鉴权
@EnableTsfRoute // 路由
@EnableTsfRateLimit // 限流
@EnableTsfSleuth // 调用链
@EnableTsfMonitor // 监控
@EnableTsfCircuitBreaker // 熔断
@EnableTsfFaultTolerance // 服务容错
@EnableTsfLane // 泳道
@TsfUnitCall // 单元化相关
@TsfUnitCustomerIdentifier // 单元化相关
@TsfUnitLocalCall // 单元化相关
@EnableTsfZoneFilter
服务容错代码定义改造
@TsfFaultTolerance 注解升级为 @FaultTolerance注解。TsfFaultToleranceProperty注解属性去除。
TsfFaultToleranceStragety 注解属性升级为 FaultToleranceStrategy 注解属性。
服务监听触发回调代码改造
Spring Cloud TSF 中服务监听触发回调的接口为 ConsulServiceChangeListener,SCT 中升级为 ServiceInstanceChangeCallback。代码实现可以参考下方示例代码:
@Component
@ServiceInstanceChangeListener(serviceName = "provider-demo")
public class ProviderServiceChangeCallback implements ServiceInstanceChangeCallback {

private static final Logger LOG = LoggerFactory.getLogger(ProviderServiceChangeCallback.class);

@Override
public void callback(List<Instance> currentServiceInstances, List<Instance> addServiceInstances, List<Instance> deleteServiceInstances) {
String current = generateNodeList(currentServiceInstances);
String add = generateNodeList(addServiceInstances);
String delete = generateNodeList(deleteServiceInstances);
LOG.info("current: {}, add: {}, delete: {}", current, add, delete);
}

private String generateNodeList(List<Instance> deleteServiceInstances) {
StringBuilder nodeListStr = new StringBuilder("[");
for (Instance instance : deleteServiceInstances) {
if (nodeListStr.length() > 1) {
nodeListStr.append(", ");
}
nodeListStr.append(instance.getHost()).append(":").append(instance.getPort());
}
nodeListStr.append("]");
return nodeListStr.toString();
}
}
API Doc 改造
Spring Cloud TSF 使用 swagger 3.0.0 实现 API Doc 的管理,SCT 使用 springdoc 2.2.0 实现。目前开源 swagger 已于2020年停止维护,相关的很多 bugfix 和漏洞不会修复,目前持续维护的是 springdoc,springdoc官方迁移文档。无法同时使用 swagger 和 springdoc,且为了您的项目的安全考虑,需要按照 springdoc 官方文档修改代码。
springdoc样例:
@RestController("/swagger")
@Tag(description = "swagger 测试", name = "swaggerValue1")
public class SwaggerApiController {

@RequestMapping(value = "/swagger/findMessages", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)
@Operation(method = "POST",
summary = "根据任务ID查询任务列表",
description = "根据任务ID查询任务列表Note")
public List<MessageModel> findMessages(@RequestBody
@Parameter(name = "msgIds", description = "消息ID列表") List<String> msgIds) {
List<MessageModel> messageModels = new ArrayList<>();
MessageModel messageModel = new MessageModel();
messageModel.setMsgContent("test1");
messageModel.setMsgId("1");
messageModel.setSendTime(System.currentTimeMillis());
MessageUser messageSender = new MessageUser();
messageSender.setEmail("abc@xxxx.com");
messageSender.setName("张三");
messageSender.setOfficeAddress("腾讯大厦");
messageSender.setPhoneNum("123123123");
messageModel.setSendUser(messageSender);
MessageUser messageReceiver = new MessageUser();
messageReceiver.setEmail("abc@xxxx.com");
messageReceiver.setName("李四");
messageReceiver.setOfficeAddress("滨海大厦");
messageReceiver.setPhoneNum("456456456");
messageModel.setReceiveUsers(Lists.newArrayList(messageReceiver));
messageModels.add(messageModel);
return messageModels;
}
}

应用管理改造

引入 Spring Cloud TSF 应用,注册到 TSF Consul 的应用详情如下图所示。



如果需要迁移到北极星网格,除了需要应用更新到 Spring Cloud Tencent,还需要编辑注册配置治理,开发框架选择 Spring Cloud,实例类别选择独享实例(北极星),然后选择可以正常连通的关联实例后,点击确认按钮。



如果当前应用存在对应的部署组,则不能直接修改注册配置治理,而是需要先删除应用下的全部部署组,或者另外新建一个应用进行迁移。