服务监听触发回调
最近更新时间: 2024-10-17 17:10:00
操作场景
服务监听允许程序监听特定服务的上下线情况,从而触发对应的业务逻辑。
前提条件
完成 【SDK 下载】。
注意:
若要使用服务监听触发回调功能,请确保 SDK 版本高于1.32。
添加依赖
向工程中添加 spring-cloud-tsf-starter
依赖并开启 @EnableTsf
注解 。
使用说明
监听 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);
}
}