Skip to content

[BUG] 通过nacos同步应用时,当只有一个服务实例,重启时会偶现"com.alibaba.nacos.api.naming.po jo.Instance.getInstanceId()" is null #6143

@BraveheartStone

Description

@BraveheartStone

Is there an existing issue for this?

  • I have searched the existing issues

Current Behavior

通过nacos发现服务时,服务只有一个实例的情况下,重启下游服务,会偶现nacos实例为空的情况。导致通过shenyu调用下游服务时报错:

"Can not find healthy upstream url, please check your configuration!"

Expected Behavior

只有一个服务重新完成后,能够正常识别应用。

Steps To Reproduce

  1. Divide中添加 Selector,通过 nacos 发现服务
  2. 下游服务只有一个实例
  3. 重启下游服务时,偶现上面错误

Environment

ShenYu version(s):2.7.0.2

Debug logs

错误日志:

[nacos.publisher-com.alibaba.nacos.client.naming.event.InstancesChangeEvent] ERROR
 com.alibaba.nacos.common.notify.NotifyCenter - Event callback exception: 
java.lang.NullPointerException: Cannot invoke "String.equals(Object)" because the return value of "com.alibaba.nacos.api.naming.po
jo.Instance.getInstanceId()" is null
        at org.apache.shenyu.registry.nacos.NacosInstanceRegisterRepository.lambda$compareInstances$3(NacosInstanceRegisterRepository.ja
va:188)
        at java.base/java.util.stream.MatchOps$1MatchSink.accept(MatchOps.java:90)
        at java.base/java.util.ArrayList$ArrayListSpliterator.tryAdvance(ArrayList.java:1602)
        at java.base/java.util.stream.ReferencePipeline.forEachWithCancel(ReferencePipeline.java:129)
        at java.base/java.util.stream.AbstractPipeline.copyIntoWithCancel(AbstractPipeline.java:527)
        at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:513)
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
        at java.base/java.util.stream.MatchOps$MatchOp.evaluateSequential(MatchOps.java:230)
        at java.base/java.util.stream.MatchOps$MatchOp.evaluateSequential(MatchOps.java:196)
        at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
        at java.base/java.util.stream.ReferencePipeline.anyMatch(ReferencePipeline.java:632)
        at org.apache.shenyu.registry.nacos.NacosInstanceRegisterRepository.lambda$compareInstances$4(NacosInstanceRegisterRepository.ja
va:188)
        at java.base/java.util.stream.ReferencePipeline$2$1.accept(ReferencePipeline.java:178)
        at java.base/java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1625)
        at java.base/java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:509)
        at java.base/java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:499)
        at java.base/java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:921)
        at java.base/java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
        at java.base/java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:682)
        at org.apache.shenyu.registry.nacos.NacosInstanceRegisterRepository.compareInstances(NacosInstanceRegisterRepository.java:189)
        at org.apache.shenyu.registry.nacos.NacosInstanceRegisterRepository.lambda$watchInstances$0(NacosInstanceRegisterRepository.java
:135)
        at com.alibaba.nacos.client.naming.event.InstancesChangeNotifier.onEvent(InstancesChangeNotifier.java:126)
        at com.alibaba.nacos.client.naming.event.InstancesChangeNotifier.onEvent(InstancesChangeNotifier.java:42)
        at com.alibaba.nacos.common.notify.DefaultPublisher.lambda$notifySubscriber$0(DefaultPublisher.java:199)
        at com.alibaba.nacos.common.notify.DefaultPublisher.notifySubscriber(DefaultPublisher.java:206)
        at com.alibaba.nacos.common.notify.DefaultPublisher.receiveEvent(DefaultPublisher.java:190)
        at com.alibaba.nacos.common.notify.DefaultPublisher.openEventHandler(DefaultPublisher.java:112)
        at com.alibaba.nacos.common.notify.DefaultPublisher.run(DefaultPublisher.java:95)

Anything else?

nacos server version:2.2.2

Image

建议修改后的方案:
org/apache/shenyu/registry/nacos/NacosInstanceRegisterRepository.java:188 :

        Set<Instance> updatedInstances = currentInstances.stream()
            .filter(currentInstance -> currentInstance.getInstanceId() != null &&
                previousInstances.stream()
                    .anyMatch(previousInstance ->
                        previousInstance.getInstanceId() != null &&
                            currentInstance.getInstanceId().equals(previousInstance.getInstanceId()) &&
                            !currentInstance.equals(previousInstance)))
            .collect(Collectors.toSet());

Metadata

Metadata

Assignees

No one assigned

    Labels

    type: bugSomething isn't working

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions