服务监听触发回调

最近更新时间:2022-06-10 11:43:45

我的收藏

操作场景

服务监听允许程序监听特定服务的上下线情况,从而触发对应的业务逻辑。

前提条件

请确保您已经参见 下载 Maven 下载安装了 Java 和 Maven,并且配置了 TSF 私服地址。
说明
若要使用服务监听触发回调功能,请确保 SDK 版本高于1.32

添加依赖

向工程中添加 spring-cloud-tsf-starter 依赖并开启 @EnableTsf 注解。
注意
如果您使用的是 1.15.0-Edgware-RELEASE/1.15.0-Finchley-RELEASE 及之前的版本,使用方法参见 Spring Cloud SDK 历史版本使用方法
1. 向工程中添加依赖。 在 pom.xml 中添加以下代码:
<dependency>
<groupId>com.tencent.tsf</groupId>
<artifactId>spring-cloud-tsf-starter</artifactId>
<version><!-- 调整为 SDK 最新版本号 --></version>
</dependency>
spring-cloud-tsf-starter 中包含了服务注册发现、服务路由、服务鉴权、服务限流、服务熔断、服务容错、服务监控、分布式配置、调用链功能。 2. 向 Application 类中添加注解 @EnableTsf
// 下面省略了无关的代码
@SpringBootApplication
@EnableTsf
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}

使用说明

监听 bean 需要使用 @ConsulServiceChangeListener@LocalServiceChangeListener注解,并且实现 ConsulServiceChangeCallback 接口。callback 接口有三个入参:
currentServices:表示当前在线的服务实例列表。
addServices:表示和上一次变更相比,新增的实例列表。
deleteServices:表示和上一次变更相比,删除的实例列表。

实现原理

初始化 spring bean 时,当检测到该 bean 有使用 @ConsulServiceChangeListener@LocalServiceChangeListener注解,并且有实现 ConsulServiceChangeCallback 接口时,开启一个定时任务,与注册中心 consul 保持长轮询,当监听服务有实例上线或下线时,会立刻触发相关事件并回调对应 bean 的 callback 方法。
说明
每个 bean 会启动一个额外线程执行,线程池的默认大小为10,如果监听服务的数量较多或 callback 里的业务逻辑较为复杂时可能会导致线程不够用,此时可以通过 spring.cloud.consul.discovery.callbackPoolSize 参数进行调整。

相关注解说明及使用示例

使用 @ConsulServiceChangeListener 注解:
/**
* @ConsulServiceChangeListener 监听当前命名空间或全局命名空间的任意服务
* serviceName: 监听服务的服务名
* global: 监听服务是否全局命名空间,默认 false。注:如果当前服务位于全局命名空间,global 属性无论 true 还是 false,都是监听全局命名空间的服务
*/
@Component
@ConsulServiceChangeListener(serviceName = "provider-demo", global = false)
public class ProviderDemoChangeCallback implements ConsulServiceChangeCallback {

private static final Logger log = LoggerFactory.getLogger(ProviderDemoChangeCallback.class);

@Override
public void callback(List<HealthService> currentServices, List<HealthService> addServices, List<HealthService> deleteServices) {
log.info("current size:{}, add size:{}, delete list:{}", currentServices.size(), addServices.size(), deleteServices.size());
log.info("current list:{}, add list:{}, delete list:{}", currentServices, addServices, deleteServices);
for (HealthService healthService: currentServices) {
// 可以从 meta 信息中获取节点对应的 TSF 信息,如部署组id、应用id、包版本
Map<String, String> meta = healthService.getService().getMeta();
String groupId = meta.get("TSF_GROUP_ID");
String applicationId = meta.get("TSF_APPLICATION_ID");
String progVersion = meta.get("TSF_PROG_VERSION");
}
}
}
使用 @LocalServiceChangeListener 注解:
/**
* @LocalServiceChangeListener 监听当前服务(spring.application.name)
* excludeLocalInstance: 回调的 currentServices 是否包含当前实例,默认为 false
*/
@Component
@LocalServiceChangeListener(excludeLocalInstance = false)
public class LocalServiceChangeCallback implements ConsulServiceChangeCallback {

private static final Logger log = LoggerFactory.getLogger(LocalServiceChangeCallback.class);

@Override
public void callback(List<HealthService> currentServices, List<HealthService> addServices, List<HealthService> deleteServices) {
log.info("current size:{}, add size:{}, delete list:{}", currentServices.size(), addServices.size(), deleteServices.size());
log.info("current list:{}, add list:{}, delete list:{}", currentServices, addServices, deleteServices);
}
}