apache / dubbo

The java implementation of Apache Dubbo. An RPC and microservice framework.
https://dubbo.apache.org/
Apache License 2.0
40.51k stars 26.43k forks source link

2.7.15 重启服务消费者,会无法找到服务提供者,需要再次重启服务提供者,2.7.8 不存在这个问题 #9661

Open wenlincheng opened 2 years ago

wenlincheng commented 2 years ago

dubbo-spring-boot-starter 2.7.15 springboot 2.3.2.RELEASE 使用nacos 2.0.3 / 1.4.1 作为注册中心

依次启动服务提供者和消费者,能正常调用,当重启服务消费者,调用会报无法找到服务提供者 org.apache.dubbo.rpc.RpcException: No provider available from registry xxxxx:80 for service ....... 再重启服务提供者,则恢复正常

配置

# Dubbo
dubbo:
  scan:
    # dubbo 服务扫描基准包
    base-packages: com.xxxx.xxxx.item.service
  # 协议
  protocols:
    # dubbo 协议
    dubbo:
      name: dubbo
      port: -1
  registry:
    address: nacos://xxxxx:80/?username=nacos&password=nacos&namespace=${spring.profiles.active}&group=ARK_SAILOR
  application:
    qos-enable: false
    logger: slf4j
  consumer:
    check: false
wenlincheng commented 2 years ago

dubbo-spring-boot-starter 降为 2.7.8 解决

wenlincheng commented 2 years ago

2.7.14也不存在这个问题

SuperEdison commented 2 years ago

去了解下dubbo的服务发现和注册流程,你会发现这是正常情况,消费者的不是一启动就可以调用生产者,他正确的顺序应该是项目启动->通过ReferenceConfig转成Protocol然后再变成Invoker最后会生成代理,而消费者并是不通过代理去调用生产者,而是在注册中心通知消费者生产者可用后回去刷新生产者的Invoker,然后去创建ExchangeClient,才会去生产rpc代理进行调用。

wenlincheng commented 2 years ago

去了解下dubbo的服务发现和注册流程,你会发现这是正常情况,消费者的不是一启动就可以调用生产者,他正确的顺序应该是项目启动->通过ReferenceConfig转成Protocol然后再变成Invoker最后会生成代理,而消费者并是不通过代理去调用生产者,而是在注册中心通知消费者生产者可用后回去刷新生产者的Invoker,然后去创建ExchangeClient,才会去生产rpc代理进行调用。

问题在于重启消费者后无法找到提供者,需要再次重启提供者才会触发注册中心通知消费者去刷新提供者的Invoker,正常情况是不需要重启提供者的,在2.7.15出现的这个问题,试过了 2.7.14、2.7.8不存在

SuperEdison commented 2 years ago

你可以去看看Nacos通知消费者可用的那一段代码。 image image image 当项目启动的时候ExchangeClient会为空,而当注册中心通知dubbo后会去创建ExchangClient并且创建代理。实际是真的没有可用生产者,如果你是双节点的话说明nacos还没通知到第一个重启的节点,你就已经重启第二个节点了,如果你是节点高可用持续发布的状态下,你可以等一个消费者启动完等待1分钟左右再去shutdown另一个节点,这样就可以有足够时间等待nacos通知,并且创建代理。nacos通知的时机并不是实时的,不是说你消费者一启动好就马上可以创建代理。而是看nacos目前的压力大小(这个仅仅我自己测过具体源码没看)。

Johnson-Jia commented 2 years ago

dubbo-spring-boot-starter 2.7.15 springboot 2.4.13 使用nacos server 2.0.4 nacos-client 2.0.4 作为注册中心 消费端提示 大量生产者不存在,但是nacos里面存在服务者, org.apache.dubbo.rpc.RpcException: No provider available from registry 10.0.1.*:8848 for service com.tbc.app.els.courseevaluateuser.CourseEvaluateUserService:1.0 on consumer 10.x.x.x use dubbo version 2.7.15, please check status of providers(disabled, not registered or in blacklist).

Johnson-Jia commented 2 years ago

替换为 dubbo-spring-boot-starter 2.7.14 dubbo 2.7.15

目前观察半小时 服务 使用正常,后面持续观察看看

Johnson-Jia commented 2 years ago

dubbo-spring-boot-starter 2.7.14 dubbo 2.7.15 springboot 2.4.13 使用nacos server 2.0.4 nacos-client 2.0.4 作为注册中心

又再次出现这个问题 , 准备把 Dubbo 换到2.7.14 试试

wenlincheng commented 2 years ago

dubbo-spring-boot-starter 2.7.14 dubbo 2.7.15 springboot 2.4.13 使用nacos server 2.0.4 nacos-client 2.0.4 作为注册中心

又再次出现这个问题 , 准备把 Dubbo 换到2.7.14 试试

应该是同一个问题,换成 dubbo-spring-boot-starter 2.7.14 运行稳定,已上生产

Johnson-Jia commented 2 years ago

问题现象以及原因: 现象: 每次修改nacos配置中心 配置文件后,过几分钟就找不到生产提供者。 分析: 是否是 自动刷新配置,重新创建bean 以及Dubbo代理对象,引起的原因?

SuperEdison commented 2 years ago

可以去看看是不是nacos原因

tangyongshuang commented 2 years ago

我遇到了同样的问题,请问 @wenlincheng 最后有没有升级到2.7.15,是怎么解决的

luyiArye commented 2 years ago

2.7.14也不存在这个问题

这个版本service带泛型注入应用起不来。

ghghhh commented 2 years ago

image 问题大概找到了,是nacosListener的问题,NacosInstanceManageUtil.initOrRefreshServiceInstanceList(serviceName, instances);这一行的serviceName其实是一直不变的,一个url生成2个服务名,比如TestService::和TestService,而这2个服务用的nacosListener是同一个并且serviceName=TestService::。

JackTianZhao commented 1 year ago

image 问题大概找到了,是nacosListener的问题,NacosInstanceManageUtil.initOrRefreshServiceInstanceList(serviceName, instances);这一行的serviceName其实是一直不变的,一个url生成2个服务名,比如TestService::和TestService,而这2个服务用的nacosListener是同一个并且serviceName=TestService::。

怎么解决呢?

AlbumenJ commented 1 year ago

请升级到 Dubbo 2.7.18 或者 3.1.2 版本,这个问题已经修复