服务监听触发回调

最近更新时间: 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);
    }
 }