Skip to content

Nacos-Client 升级到 2.1.1 导致实例订阅事件失效 #9227

@ruansheng8

Description

@ruansheng8

Describe the bug
A clear and concise description of what the bug is.
Nacos-Client version : 2.1.1

Actually behavior
使用 nacos-client 2.0.4 版本进行事件订阅可正常收到实例的变更 , 升级到 nacos-client 2.1.1 会导致其订阅失效

How to Reproduce

原因

排查后发现是由于解决 #8433 这个issue导致的 , 该Issue增加了eventScope唯一标识来区分事件不同的域 , 并且给 com.alibaba.nacos.common.notify.listener.Subscriber 这个抽象类增加了一个scopeMatches 方法 , 该方法不是抽象的 , 以前所有旧版本升级到2.1.1版本后 , 开发者并不知道去重写该方法 , 导致了订阅失效

以下是Subscriber 新增的方法 , 默认判断event.scope() == null 的情况事件生效 , 当时框架创建的InstancesChangeEvent中的eventScope永远不为空 (默认是在创建的时候给了一个UUID) , 从而导致自定义的订阅事件没有重写scopeMatches方法的话结果永远是false

    public boolean scopeMatches(T event) {
        return event.scope() == null;
    }

部分源码: NacosNamingService.java
image

部分源码: ServiceInfoHolder.java
image

部分源码: DefaultPublisher.java
image

Bug复现

以下是复现的代码 , 通过切换本地的nacos-client 版本 , 2.0.4 版本可以正常收到实例变更事件 , 2.1.1 版本不行

    public static void main(String[] args) throws Exception {
        new Thread(() -> {
            try {
                NamingService namingService = NacosFactory.createNamingService("192.168.4.89:8848");
                namingService.subscribe("case-template-service", "SERVICE_GROUP", event -> {
                });
                NotifyCenter.registerSubscriber(new Subscriber<InstancesChangeEvent>() {
                    @Override
                    public void onEvent(InstancesChangeEvent event) {
                        System.out.println("收到实例变更事件: " + event);
                    }

                    @Override
                    public Class<? extends Event> subscribeType() {
                        return InstancesChangeEvent.class;
                    }
                });
            } catch (Exception e) {
                e.printStackTrace();
            }
        }).start();
        Thread.sleep(1000 * 60 * 10);
    }

解决方案

重写Subscriber 的scopeMatches方法 , 返回true时生效

                    @Override
                    public boolean scopeMatches(InstancesChangeEvent event) {
                        // 默认对所有namingService生效
                        return true;
                    }

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions