地址找不到异常

在 Dubbo 抛出地址找不到异常的时候的排查思路

在开发与生产部署过程中,由于 Dubbo 是一个需要基于服务发现功能进行调用的框架,很容易由于各种客观原因出现 No Provder 的异常,本文旨在通过体系化的排查思路,让您能够在异常的时候快速定位原因并解决。

  1. java.lang.IllegalStateException: Failed to check the status of the service org.apache.dubbo.samples.api.GreetingsService. No provider available for the service org.apache.dubbo.samples.api.GreetingsService from the url consumer://*** to the consumer 30.221.146.226 use dubbo version 3.2.0-beta.4
  1. Exception in thread "main" org.apache.dubbo.rpc.RpcException: No provider available from registry 127.0.0.1:2181 for service org.apache.dubbo.samples.api.GreetingsService on consumer 30.221.146.226 use dubbo version 3.2.0-beta.4, please check status of providers(disabled, not registered or in blacklist).

一句话总结

服务找不到时先自查服务是否已经开发完部署了,然后在注册中心中确认是否已经注册,如果注册检查服务端发布情况、如果未注册检查消费端订阅情况,中间任何一步出问题都会导致异常。

排查思路全览

img

详细教程

1 识别异常的服务以及订阅模式

为了后续正确定位排查的方向,第一步需要先确认有报错的服务名。

img img img img

如上图所示,常见的地址找不到异常报错中会包括对应的服务名,格式有以下两种。

  1. No provider available for the service ${serviceName}
  2. No provider available from registry ${registryAddress} for service ${serviceName}

在这个报错日志中可以提取出报错对应的服务名。此处需要注意关注对应的分组与版本号,通常格式如下:

  1. ${group}/${interfaceName}:${version}

除了获取报错对应的服务名外,还需要获取该服务的订阅模式。(默认通常为 APPLICATION_FIRST 也即是双订阅模式)

如一下日志所示,可以在 Dubbo 的日志中搜索 [DUBBO] Succeed Migrated to 关键字,获取对应的订阅模式。

  1. [26/02/23 03:27:07:007 CST] main INFO migration.MigrationRuleHandler: [DUBBO] Succeed Migrated to APPLICATION_FIRST mode. Service Name: org.apache.dubbo.samples.api.GreetingsService, dubbo version: 3.2.0-beta.6-SNAPSHOT, current host: 192.168.31.5

当前 Dubbo 共有三种订阅模式:

  • FORCE_INTERFACE:仅订阅接口级服务发现模型的数据,这种数据为 2.7.x 及之前的 Dubbo 版本发布的数据模型。
  • FORCE_APPLICATION:仅应用级服务发现模型的数据,这种数据为 3.x 版本开始 Dubbo 为云原生大规模部署的应用所设计的数据模型。
  • APPLICATION_FIRST:同时订阅接口级服务发现模型和应用级服务发现模型的数据,任何一种模型下有数据都可以调用,默认优先使用应用级服务发现模型的数据。

如果该有问题的服务的订阅模式为 FORCE_INTERFACE,则后续排查中需要检查接口级的地址是否正常发布;如果为 FORCE_APPLICATION 则需要检查应用级地址是否正常发布;如果为 APPLICATION_FIRST 则任意一种地址模型发布都可以。

2 查询注册中心是否存在服务

2.1 通过 Dubbo Admin 查询(推荐)

如果您的集群中部署了 Dubbo Admin,可以直接 Dubbo Admin 的控制台中的“服务查询”模块查询该服务的注册情况。 img img

如上图所示,请结合前述第 1 步中服务发现模型确认是否能查询到预期的服务端。 如果能查到,请跳转到第 x 步继续排查,如果不能查到请跳转到第 3 步进行排查。

2.2 通过注册中心查询

如果您没有部署 Dubbo Admin,则可以通过注册中心直接查询原始数据。

2.2.1 Nacos 注册中心

1)接口级服务发现 在接口级服务发现模型下,可以直接通过 Nacos 控制台查询服务信息,入口为 “服务管理” - “服务列表”,输入服务名在服务名称一栏搜索即可查询。

注:Nacos 注册中心下,Dubbo 服务名与 Nacos 服务名映射关系为 providers:${interfaceName}:${version}:${group},如 dev/com.example.DemoService:1.0.0 映射为 providers:com.example.DemoService:1.0.0:dev

img

如上图所示,请结合前述第 1 步中服务发现模型确认是否能查询到预期的服务端。 如果能查到,请跳转到第 x 步继续排查,如果不能查到请跳转到第 3 步进行排查。

2)应用级服务发现 在应用级服务发现模型下,需要先查询服务映射的信息,入口为 “配置管理” - “配置列表”,Data ID 为接口名,Group 为 mapping

注:查询服务映射时 Data ID 为接口名,不需要填写分组、版本号。

img

img

如上图所示,查询该配置的配置内容中是否存在预期的应用名。 如果能查到,请以该应用名为服务名称继续排查,如果不能查到请跳转到第 3 步进行排查。

在查询到应用名以后,需要进一步查询服务信息,入口为 “服务管理” - “服务列表”,输入服务名在服务名称一栏搜索即可查询。

注:此处的服务名称为上一步查询出的应用名,非接口名。

img

如上图所示,请结合前述第 1 步中服务发现模型确认是否能查询到预期的服务端。 如果能查到,请跳转到第 x 步继续排查,如果不能查到请跳转到第 3 步进行排查。

2.2.2 通过 Zookeeper 注册中心查询

1)接口级服务发现 在接口级服务发现模型下,可以直接通过 Zookeeper 命令行查询服务信息,路径为 /dubbo/${interfaceName}/providers

注:Zookeeper 注册中心中路径上为接口名,分组和版本号在地址参数上,如果您指定了服务的分组或版本号,需要检查每个地址的参数。

  1. [zk: localhost:2181(CONNECTED) 1] ls /dubbo/org.apache.dubbo.samples.api.GreetingsService/providers
  2. [dubbo%3A%2F%2F30.221.144.195%3A20880%2Forg.apache.dubbo.samples.api.GreetingsService%3Fanyhost%3Dtrue%26application%3Dfirst-dubbo-provider%26background%3Dfalse%26deprecated%3Dfalse%26dubbo%3D2.0.2%26dynamic%3Dtrue%26environment%3Dproduct%26executor-management-mode%3Ddefault%26file-cache%3Dtrue%26generic%3Dfalse%26interface%3Dorg.apache.dubbo.samples.api.GreetingsService%26methods%3DsayHi%26pid%3D37828%26prefer.serialization%3Dfastjson2%2Chessian2%26release%3D3.2.0-beta.6-SNAPSHOT%26service-name-mapping%3Dtrue%26side%3Dprovider%26timestamp%3D1677463548624]

如上所示,请结合前述第 1 步中服务发现模型确认是否能查询到预期的服务端。 如果能查到,请跳转到第 x 步继续排查,如果不能查到请跳转到第 3 步进行排查。

2)应用级服务发现 在应用级服务发现模型下,需要先查询服务映射的信息,可以通过 Zookeeper 的命令行工具查询,路径为 /dubbo/mapping/${interfaceName}

注:查询服务映射时 interfaceName 为接口名,不需要填写分组、版本号。

  1. [zk: localhost:2181(CONNECTED) 6] get /dubbo/mapping/org.apache.dubbo.samples.api.GreetingsService
  2. first-dubbo-provider

如上所示,查询该配置的配置内容中是否存在预期的应用名。 如果能查到,请以该应用名为服务名称继续排查,如果不能查到请跳转到第 3 步进行排查。

在查询到应用名以后,需要进一步查询服务信息,可以直接通过 Zookeeper 命令行查询服务信息,路径为 /services/${interfaceName}

注:此处的服务名称为上一步查询出的应用名,非接口名。

  1. [zk: localhost:2181(CONNECTED) 7] ls /services/first-dubbo-provider
  2. [30.221.144.195:20880]

如上图所示,请结合前述第 1 步中服务发现模型确认是否能查询到预期的服务端。 如果能查到,请跳转到第 x 步继续排查,如果不能查到请跳转到第 3 步进行排查。

注:如果采用了应用级服务发现模型后检查消费端地址仍找不到则可能是该服务端没有发布对应的服务,请从第 3 步开始排查。

3 检查服务端是否已经发布服务

3.1 通过 Dubbo QoS 查询(推荐)

在 Dubbo 应用启动的时候,默认会在本地的 22222 端口发布一个 QoS 服务,可以用于运行时查询节点的状态。通常,如果没有独立配置 dubbo.application.qos-enable 或者 dubbo.application.qos-port 都可以基于本方法查询服务的信息。

找到预期发布该服务的机器,登陆到其控制台,执行 telnet 127.0.0.1 22222ls

  1. telnet 127.0.0.1 22222
  2. Trying 127.0.0.1...
  3. Connected to localhost.
  4. Escape character is '^]'.
  5. ___ __ __ ___ ___ ____
  6. / _ \ / / / // _ ) / _ ) / __ \
  7. / // // /_/ // _ |/ _ |/ /_/ /
  8. /____/ \____//____//____/ \____/
  9. dubbo>ls
  10. As Provider side:
  11. +------------------------------------------------------------------------------------+---------------------+
  12. | Provider Service Name | PUB |
  13. +------------------------------------------------------------------------------------+---------------------+
  14. | org.apache.dubbo.samples.api.GreetingsService |nacos-A(Y)/nacos-I(Y)|
  15. +------------------------------------------------------------------------------------+---------------------+
  16. |DubboInternal - first-dubbo-provider/org.apache.dubbo.metadata.MetadataService:1.0.0| |
  17. +------------------------------------------------------------------------------------+---------------------+
  18. As Consumer side:
  19. +---------------------+---+
  20. |Consumer Service Name|NUM|
  21. +---------------------+---+
  22. dubbo>

如果机器上没有 telnet 也可以通过 cURL 发起调用,请求地址为 http://127.0.0.1:22222/ls

  1. curl http://127.0.0.1:22222/ls
  2. As Provider side:
  3. +------------------------------------------------------------------------------------+---------------------+
  4. | Provider Service Name | PUB |
  5. +------------------------------------------------------------------------------------+---------------------+
  6. | org.apache.dubbo.samples.api.GreetingsService |nacos-A(Y)/nacos-I(Y)|
  7. +------------------------------------------------------------------------------------+---------------------+
  8. |DubboInternal - first-dubbo-provider/org.apache.dubbo.metadata.MetadataService:1.0.0| |
  9. +------------------------------------------------------------------------------------+---------------------+
  10. As Consumer side:
  11. +---------------------+---+
  12. |Consumer Service Name|NUM|
  13. +---------------------+---+

注:默认情况下 ls 命令仅允许本机调用,如果您无法登陆对应的机器,请参考 3.2 通过日志进行检查。

如上结果所示,请检查在 As Provider side 一栏中是否存在您所发布的服务名,如果存在则代表该服务已经发布。 第二列 PUB 中的信息为该服务的注册情况,格式为 ${registryName}-${registerType}(${status})registerType 有两种情况,分别是 AI 代表着应用级服务发现模型和接口级服务发现模型。可以通过该信息判断服务发布的情况。

如果您无法找到您所发布的服务,请检查以下清单:

  1. 该服务是否已经添加到该机器所对应的运行代码中
  2. 该服务是否已经正确配置到 Dubbo 环境中,请检查如 @EnableDubbo@DubboService 或者 XML 等配置是否正确

如果您找到了您所发布的服务,但是服务状态是 N,请检查以下清单:

  1. 该服务配置了 register=false
  2. 是否有外部的命令调用了 offline
  3. 应用是否启动成功(包括但不限于如 Tomcat、Spring 的启动状态)

如果您找到了您所发布的服务,但是对应的服务发现模型错误,请检查以下清单:

  1. 注册中心地址是否配置了 registry-type=service
  2. 是否配置了应用级的注册模式,如 dubbo.application.register-type

如果您找到了您所发布的服务,且对应的服务发现模型下服务状态是 Y,请跳转到第 4 步进行排查。

3.2 通过日志检查

如果您由于各种原因无法使用 Dubbo QoS,可以在对应机器的日志上搜索 [DUBBO] Export dubbo service ${serviceName} 来检查服务是否已经发布。

  1. [26/02/23 04:34:41:041 CST] main INFO config.ServiceConfig: [DUBBO] Export dubbo service org.apache.dubbo.samples.api.GreetingsService to local registry url : injvm://***, dubbo version: 3.1.7, current host: 192.168.31.5

如上所示,则代表着该服务已经发布,如果您无法找到您所发布的服务,请检查以下清单:

  1. 该服务是否已经添加到该机器所对应的运行代码中
  2. 该服务是否已经正确配置到 Dubbo 环境中,请检查如 @EnableDubbo@DubboService 或者 XML 等配置是否正确

在确定了服务已经发布了以后,可以在对应机器的日志上搜索 [DUBBO] Register dubbo service ${serviceName} to registry ${registryAddress} 来检查服务是否已经注册。

  1. [26/02/23 04:34:41:041 CST] main INFO config.ServiceConfig: [DUBBO] Register dubbo service org.apache.dubbo.samples.api.GreetingsService url dubbo://*** to registry 127.0.0.1:8848, dubbo version: 3.1.7, current host: 192.168.31.5

如上所示,则代表着该服务已经注册,如果您无法找到相关日志,请检查以下清单:

  1. 该服务配置了 register=false
  2. 是否有外部的命令调用了 offline
  3. 应用是否启动成功(包括但不限于如 Tomcat、Spring 的启动状态)

如果您找到了您所注册的服务,请跳转到第 4 步进行排查。

4 检查服务端注册中心配置

4.1 通过 Dubbo Admin 查询(推荐)

注:Dubbo 3.2.0 及以上版本支持

在 Dubbo 应用启动的时候,默认会在本地的 22222 端口发布一个 QoS 服务,可以用于运行时查询节点的状态。通常,如果没有独立配置 dubbo.application.qos-enable 或者 dubbo.application.qos-port 都可以基于本方法查询服务的信息。

找到预期发布该服务的机器,登陆到其控制台,执行 telnet 127.0.0.1 22222getConfig RegistryConfig

  1. telnet 127.0.0.1 22222
  2. Trying 127.0.0.1...
  3. Connected to localhost.
  4. Escape character is '^]'.
  5. ___ __ __ ___ ___ ____
  6. / _ \ / / / // _ ) / _ ) / __ \
  7. / // // /_/ // _ |/ _ |/ /_/ /
  8. /____/ \____//____//____/ \____/
  9. dubbo>getConfig RegistryConfig
  10. ApplicationModel: Dubbo Application[1.1](first-dubbo-provider)
  11. RegistryConfig: null
  12. <dubbo:registry address="nacos://127.0.0.1:8848" protocol="nacos" port="8848" />

如上述结果所示,请检查对应的注册中心配置是否符合预期,如果不符合请修改对应的配置。 如果第 3 步和第 4 步检查均符合预期,则该服务应该可以在第 2 步的注册中心中查询到,如果查询不到请检查注册中心是否工作正常。

注:getConfig 命令仅允许本机调用,如果您无法登陆对应的机器,请参考 4.2 通过日志进行检查。

4.2 通过日志检查

如果您由于各种原因无法使用 Dubbo QoS,可以在对应机器的日志上搜索 [DUBBO] <dubbo:registry address= 来检查注册中心的配置。

  1. [27/02/23 09:36:46:046 CST] main INFO context.ConfigManager: [DUBBO] <dubbo:registry address="nacos://127.0.0.1:8848" protocol="nacos" port="8848" />, dubbo version: 3.2.0-beta.6-SNAPSHOT, current host: 30.221.144.195

如上述结果所示,请检查对应的注册中心配置是否符合预期,如果不符合请修改对应的配置。 如果第 3 步和第 4 步检查均符合预期,则该服务应该可以在第 2 步的注册中心中查询到,如果查询不到请检查注册中心是否工作正常。

5 检查服务端网络配置

在服务端发布了服务以后,请检查网络防火墙(iptables、ACL 等)是否允许 Dubbo 端口进行通信,默认 Dubbo 协议端口号为 20880、Triple 协议端口号为 50051。具体端口号可以从第 2 步注册中心中的信息获取。

测试方式:在消费端机器直接 telnet 远程的端口。

6 检查消费端是否订阅服务

6.1 通过 Dubbo QoS 查询(推荐)

在 Dubbo 应用启动的时候,默认会在本地的 22222 端口发布一个 QoS 服务,可以用于运行时查询节点的状态。通常,如果没有独立配置 dubbo.application.qos-enable 或者 dubbo.application.qos-port 都可以基于本方法查询服务的信息。

找到预期发布该服务的机器,登陆到其控制台,执行 telnet 127.0.0.1 22222ls

  1. telnet 127.0.0.1 22222
  2. Trying 127.0.0.1...
  3. Connected to localhost.
  4. Escape character is '^]'.
  5. ___ __ __ ___ ___ ____
  6. / _ \ / / / // _ ) / _ ) / __ \
  7. / // // /_/ // _ |/ _ |/ /_/ /
  8. /____/ \____//____//____/ \____/
  9. dubbo>ls
  10. As Provider side:
  11. +------------------------------------------------------------------------------------+---+
  12. | Provider Service Name |PUB|
  13. +------------------------------------------------------------------------------------+---+
  14. |DubboInternal - first-dubbo-consumer/org.apache.dubbo.metadata.MetadataService:1.0.0| |
  15. +------------------------------------------------------------------------------------+---+
  16. As Consumer side:
  17. +---------------------------------------------+---------------------+
  18. | Consumer Service Name | NUM |
  19. +---------------------------------------------+---------------------+
  20. |org.apache.dubbo.samples.api.GreetingsService|zookeeper-AF(I-1,A-1)|
  21. +---------------------------------------------+---------------------+
  22. dubbo>

如果机器上没有 telnet 也可以通过 cURL 发起调用,请求地址为 http://127.0.0.1:22222/ls

  1. curl http://127.0.0.1:22222/ls
  2. As Provider side:
  3. +------------------------------------------------------------------------------------+---+
  4. | Provider Service Name |PUB|
  5. +------------------------------------------------------------------------------------+---+
  6. |DubboInternal - first-dubbo-consumer/org.apache.dubbo.metadata.MetadataService:1.0.0| |
  7. +------------------------------------------------------------------------------------+---+
  8. As Consumer side:
  9. +---------------------------------------------+---------------------+
  10. | Consumer Service Name | NUM |
  11. +---------------------------------------------+---------------------+
  12. |org.apache.dubbo.samples.api.GreetingsService|zookeeper-AF(I-1,A-1)|
  13. +---------------------------------------------+---------------------+

注:默认情况下 ls 命令仅允许本机调用,如果您无法登陆对应的机器,请参考 3.2 通过日志进行检查。

如上结果所示,请检查在 As Consumer side 一栏中是否存在您所发布的服务名,如果存在则代表该服务已经发布。 第二列 NUM 中的信息为该服务的注册情况,格式为 ${registryName}-${migrationType}(${level}-${count})

  1. migrationType 有三种情况,分别是 AFFAFI 代表着订阅的模式。AF 会优先使用应用级模型下的地址,如果应用级地址找不到会自动使用接口级模型的地址。FAFI 则会只使用应用级模型的地址和接口级模型的地址。
  2. level 有两种情况,分别是 IA,代表着接口级模型下的地址和应用级模型下的地址。

如果您无法找到您所发布的服务,请检查以下清单:

  1. 该服务是否已经添加到该机器所对应的运行代码中
  2. 该服务是否已经正确配置到 Dubbo 环境中,请检查如 @EnableDubbo@DubboReference 或者 XML 等配置是否正确

如果您找到了您所发布的服务,但是服务的地址数是 0,请检查以下清单:

  1. 注册中心的工作状态
  2. 从第 2 步重新排查

如果您找到了您所发布的服务,但是对应的服务发现模型错误,请检查以下清单:

  1. 是否配置的订阅迁移规则,如 dubbo-migration.yaml 或动态配置,请参考 应用级服务发现地址迁移规则说明

如果您找到了您所发布的服务,且对应的服务发现模型下地址数非 0,请跳转到第 7 步进行排查。

6.2 通过日志检查

如果您由于各种原因无法使用 Dubbo QoS,可以在对应机器的日志上搜索 [DUBBO] Subscribe: 来检查服务是否已经订阅。

  1. [27/02/23 11:02:05:005 CST] main INFO zookeeper.ZookeeperRegistry: [DUBBO] Subscribe: consumer://***/org.apache.dubbo.samples.api.GreetingsService?***, dubbo version: 3.2.0-beta.6, current host: 30.221.144.195

如上所示,则代表着该服务已经发布,如果您无法找到您所发布的服务,请检查以下清单:

  1. 该服务是否已经添加到该机器所对应的运行代码中
  2. 该服务是否已经正确配置到 Dubbo 环境中,请检查如 @EnableDubbo@DubboReference 或者 XML 等配置是否正确

在确定了服务已经订阅了以后,可以在对应机器的日志上搜索 [DUBBO] Received invokers changed event from registry. 来检查服务是否已经推送。

  1. [27/02/23 11:02:05:005 CST] main INFO integration.RegistryDirectory: [DUBBO] Received invokers changed event from registry. Registry type: interface. Service Key: org.apache.dubbo.samples.api.GreetingsService. Urls Size : 1. Invokers Size : 1. Available Size: 1. Available Invokers : 30.221.144.195:20880, dubbo version: 3.2.0-beta.6, current host: 30.221.144.195

如上所示,则代表着该服务已经推送,如果您无法找到相关日志,请检查以下清单:

  1. 注册中心的工作状态
  2. 从第 2 步重新排查

如果您找到了您所注册的服务,请跳转到第 7 步进行排查。

注:推送日志仅 3.2.0 及以上版本支持

7 检查消费端注册中心配置

注:本小节排查思路与第 4 步检查服务端注册中心配置类似。

7.1 通过 Dubbo Admin 查询(推荐)

注:Dubbo 3.2.0 及以上版本支持

在 Dubbo 应用启动的时候,默认会在本地的 22222 端口发布一个 QoS 服务,可以用于运行时查询节点的状态。通常,如果没有独立配置 dubbo.application.qos-enable 或者 dubbo.application.qos-port 都可以基于本方法查询服务的信息。

找到预期发布该服务的机器,登陆到其控制台,执行 telnet 127.0.0.1 22222getConfig RegistryConfig

  1. telnet 127.0.0.1 22222
  2. Trying 127.0.0.1...
  3. Connected to localhost.
  4. Escape character is '^]'.
  5. ___ __ __ ___ ___ ____
  6. / _ \ / / / // _ ) / _ ) / __ \
  7. / // // /_/ // _ |/ _ |/ /_/ /
  8. /____/ \____//____//____/ \____/
  9. dubbo>getConfig RegistryConfig
  10. ApplicationModel: Dubbo Application[1.1](first-dubbo-provider)
  11. RegistryConfig: null
  12. <dubbo:registry address="nacos://127.0.0.1:8848" protocol="nacos" port="8848" />

如上述结果所示,请检查对应的注册中心配置是否符合预期,如果不符合请修改对应的配置。 如果第 6 步和第 7 步检查均符合预期,则该服务应该可以在第 2 步的注册中心中查询到,如果查询不到请检查注册中心是否工作正常。

注:getConfig 命令仅允许本机调用,如果您无法登陆对应的机器,请参考 4.2 通过日志进行检查。

7.2 通过日志检查

如果您由于各种原因无法使用 Dubbo QoS,可以在对应机器的日志上搜索 [DUBBO] <dubbo:registry address= 来检查注册中心的配置。

  1. [27/02/23 09:36:46:046 CST] main INFO context.ConfigManager: [DUBBO] <dubbo:registry address="nacos://127.0.0.1:8848" protocol="nacos" port="8848" />, dubbo version: 3.2.0-beta.6-SNAPSHOT, current host: 30.221.144.195

如上述结果所示,请检查对应的注册中心配置是否符合预期,如果不符合请修改对应的配置。 如果第 3 步和第 4 步检查均符合预期,则该服务应该可以在第 2 步的注册中心中查询到,如果查询不到请检查注册中心是否工作正常。

8 检查注册中心推送的地址信息

注:本小节中使用的查询命令 Dubbo 3.2.0 及以上版本支持

在 Dubbo 应用启动的时候,默认会在本地的 22222 端口发布一个 QoS 服务,可以用于运行时查询节点的状态。通常,如果没有独立配置 dubbo.application.qos-enable 或者 dubbo.application.qos-port 都可以基于本方法查询服务的信息。

找到预期发布该服务的机器,登陆到其控制台,执行 telnet 127.0.0.1 22222getAddress ${serviceName}

  1. telnet 127.0.0.1 22222
  2. Trying 127.0.0.1...
  3. Connected to localhost.
  4. Escape character is '^]'.
  5. ___ __ __ ___ ___ ____
  6. / _ \ / / / // _ ) / _ ) / __ \
  7. / // // /_/ // _ |/ _ |/ /_/ /
  8. /____/ \____//____//____/ \____/
  9. dubbo>getAddress org.apache.dubbo.samples.api.GreetingsService
  10. ConsumerModel: org.apache.dubbo.samples.api.GreetingsService@38b2d161
  11. Registry: zookeeper://127.0.0.1:2181/org.apache.dubbo.registry.RegistryService?application=first-dubbo-consumer&dubbo=2.0.2&environment=product&executor-management-mode=default&file-cache=true&interface=org.apache.dubbo.registry.RegistryService&pid=44482&release=3.2.0-beta.6-SNAPSHOT
  12. MigrationStep: APPLICATION_FIRST
  13. Interface-Level:
  14. All Invokers:
  15. dubbo://30.221.144.195:20880/org.apache.dubbo.samples.api.GreetingsService?anyhost=true&application=first-dubbo-provider&background=false&check=false&deprecated=false&dubbo=2.0.2&dynamic=true&executor-management-mode=default&file-cache=true&generic=false&interface=org.apache.dubbo.samples.api.GreetingsService&methods=sayHi&prefer.serialization=fastjson2,hessian2&release=3.2.0-beta.6-SNAPSHOT&service-name-mapping=true&side=provider
  16. Valid Invokers:
  17. dubbo://30.221.144.195:20880/org.apache.dubbo.samples.api.GreetingsService?anyhost=true&application=first-dubbo-provider&background=false&check=false&deprecated=false&dubbo=2.0.2&dynamic=true&executor-management-mode=default&file-cache=true&generic=false&interface=org.apache.dubbo.samples.api.GreetingsService&methods=sayHi&prefer.serialization=fastjson2,hessian2&release=3.2.0-beta.6-SNAPSHOT&service-name-mapping=true&side=provider
  18. Disabled Invokers:
  19. Application-Level:
  20. All Invokers:
  21. dubbo://30.221.144.195:20880/org.apache.dubbo.samples.api.GreetingsService?anyhost=true&application=first-dubbo-consumer&background=false&deprecated=false&dubbo=2.0.2&dubbo.endpoints=[{"port":20880,"protocol":"dubbo"}]&dubbo.metadata-service.url-params={"prefer.serialization":"fastjson2,hessian2","version":"1.0.0","dubbo":"2.0.2","release":"3.2.0-beta.6-SNAPSHOT","side":"provider","port":"20880","protocol":"dubbo"}&dubbo.metadata.revision=e37fc5748b33c325056556550d33dde7&dubbo.metadata.storage-type=local&dynamic=true&environment=product&executor-management-mode=default&file-cache=true&generic=false&interface=org.apache.dubbo.samples.api.GreetingsService&methods=sayHi&pid=44482&prefer.serialization=fastjson2,hessian2&register.ip=30.221.144.195&release=3.2.0-beta.6-SNAPSHOT&service-name-mapping=true&side=consumer&sticky=false&timestamp=1677466879396&unloadClusterRelated=false
  22. Valid Invokers:
  23. dubbo://30.221.144.195:20880/org.apache.dubbo.samples.api.GreetingsService?anyhost=true&application=first-dubbo-consumer&background=false&deprecated=false&dubbo=2.0.2&dubbo.endpoints=[{"port":20880,"protocol":"dubbo"}]&dubbo.metadata-service.url-params={"prefer.serialization":"fastjson2,hessian2","version":"1.0.0","dubbo":"2.0.2","release":"3.2.0-beta.6-SNAPSHOT","side":"provider","port":"20880","protocol":"dubbo"}&dubbo.metadata.revision=e37fc5748b33c325056556550d33dde7&dubbo.metadata.storage-type=local&dynamic=true&environment=product&executor-management-mode=default&file-cache=true&generic=false&interface=org.apache.dubbo.samples.api.GreetingsService&methods=sayHi&pid=44482&prefer.serialization=fastjson2,hessian2&register.ip=30.221.144.195&release=3.2.0-beta.6-SNAPSHOT&service-name-mapping=true&side=consumer&sticky=false&timestamp=1677466879396&unloadClusterRelated=false
  24. Disabled Invokers:
  25. dubbo>

如上述结果所示,格式如下:

  1. ConsumerModel: 订阅的信息
  2. Registry: 注册中心地址
  3. MigrationStep: 迁移模型(FORCE_APPLICATION, APPLCATION_FIRST, FORCE_INTERFACE)
  4. Interface-Level: 接口级服务发现模型下地址
  5. All Invokers:
  6. 从注册中心推送的所有地址
  7. Valid Invokers:
  8. 所有可用地址
  9. Disabled Invokers:
  10. 所有被拉黑的地址(通常是主动下线)
  11. Application-Level: 应用级服务发现模型下地址
  12. All Invokers:
  13. 从注册中心推送的所有地址
  14. Valid Invokers:
  15. 所有可用地址
  16. Disabled Invokers:
  17. 所有被拉黑的地址(通常是主动下线)

请检查对应迁移模型是否符合预期,默认为 APPLCATION_FIRST,如果对应的服务发现模型错误,请检查以下清单:

  1. 是否配置的订阅迁移规则,如 dubbo-migration.yaml 或动态配置,请参考 应用级服务发现地址迁移规则说明

如果迁移模型正确,请检查对应模型下的所有地址是否符合预期,如果不符合预期,请检查以下清单:

  1. 注册中心的工作状态
  2. 从第 2 步重新排查

如果注册中心推送的地址符合预期,请检查可用地址是否符合预期,如果不符合预期,一般为连接异常导致的自动拉黑,通常在四层网络不通或者机房断网等情况下出现,请跳转到第 9 步进行排查。

如果可用地址符合预期,请跳转到第 10 步进行检查。

注:getAddress 命令仅允许本机调用。

9 检查消费端与服务端网络连通性

在服务端发布了服务以后,请检查网络防火墙(iptables、ACL 等)是否允许 Dubbo 端口进行通信,默认 Dubbo 协议端口号为 20880、Triple 协议端口号为 50051。具体端口号可以从第 2 步注册中心中的信息获取。

测试方式:在消费端机器直接 telnet 远程的端口。

常见异常场景:

  1. 服务端消费端多集群部署,但是底层网络未打通
  2. 生产与测试共用注册中心,但是测试环境无法调用生产服务(Dubbo 极其不推荐测试与生产环境混用
  3. 单机调试,但是网络与大测试网不通
  4. 机房断网导致的节点断连
  5. 四层网络 ACL 规则未开放 Dubbo 端口访问
  6. 网络质量低、服务端负载过高等导致的网络连接质量差

10 检查路由信息

注:Dubbo 3.1.0 及以上版本支持

10.1 报错时检查日志

在 Dubbo 出现调用异常的时候,可以在对应机器的日志上搜索 [DUBBO] No provider available after route for the service 来检查路由的状态。

  1. [27/02/23 11:33:16:016 CST] main WARN cluster.SingleRouterChain: [DUBBO] No provider available after route for the service org.apache.dubbo.samples.api.GreetingsService from registry 30.221.144.195 on the consumer 30.221.144.195 using the dubbo version 3.2.0-beta.6-SNAPSHOT. Router snapshot is below:
  2. [ Parent (Input: 1) (Current Node Output: 1) (Chain Node Output: 0) ] Input: 30.221.144.195:20880 -> Chain Node Output: Empty
  3. [ MockInvokersSelector (Input: 1) (Current Node Output: 1) (Chain Node Output: 0) Router message: invocation.need.mock not set. Return normal Invokers. ] Current Node Output: 30.221.144.195:20880
  4. [ StandardMeshRuleRouter (Input: 1) (Current Node Output: 1) (Chain Node Output: 0) Router message: MeshRuleCache has not been built. Skip route. ] Current Node Output: 30.221.144.195:20880
  5. [ TagStateRouter (Input: 1) (Current Node Output: 0) (Chain Node Output: 0) Router message: Disable Tag Router. Reason: tagRouterRule is invalid or disabled ] Current Node Output: Empty, dubbo version: 3.2.0-beta.6-SNAPSHOT, current host: 30.221.144.195, error code: 2-2. This may be caused by No provider available after route for the service, go to https://dubbo.apache.org/faq/2/2 to find instructions

请检查对应的 Current Node Output: 0 所在的日志行,通常为该级路由导致的地址为空。

10.2 通过 Dubbo Admin 采样查询

对于线上运行的机器,Dubbo 提供了路由结果动态采样的能力,可以通过 Dubbo QoS 开启。

开启采样的方式:

  1. dubbo>enableRouterSnapshot com.dubbo.*
  2. OK. Found service count: 1. This will cause performance degradation, please be careful!
  3. dubbo>

获取采样结果:

  1. dubbo>getRecentRouterSnapshot
  2. 1658224330156 - Router snapshot service com.dubbo.dubbointegration.BackendService from registry 172.18.111.184 on the consumer 172.18.111.184 using the dubbo version 3.0.9 is below:
  3. [ Parent (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) ] Input: 172.18.111.187:20880,172.18.111.183:20880 -> Chain Node Output: 172.18.111.187:20880,172.18.111.183:20880
  4. [ MockInvokersSelector (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: invocation.need.mock not set. Return normal Invokers. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880
  5. [ StandardMeshRuleRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: MeshRuleCache has not been built. Skip route. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880
  6. [ TagStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: Disable Tag Router. Reason: tagRouterRule is invalid or disabled ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880
  7. [ ServiceStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: Directly return. Reason: Invokers from previous router is empty or conditionRouters is empty. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880
  8. [ AppStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: Directly return. Reason: Invokers from previous router is empty or conditionRouters is empty. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880
  9. 1658224330156 - Router snapshot service com.dubbo.dubbointegration.BackendService from registry 172.18.111.184 on the consumer 172.18.111.184 using the dubbo version 3.0.9 is below:
  10. [ Parent (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) ] Input: 172.18.111.187:20880,172.18.111.183:20880 -> Chain Node Output: 172.18.111.187:20880,172.18.111.183:20880
  11. [ MockInvokersSelector (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: invocation.need.mock not set. Return normal Invokers. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880
  12. [ StandardMeshRuleRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: MeshRuleCache has not been built. Skip route. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880
  13. [ TagStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: Disable Tag Router. Reason: tagRouterRule is invalid or disabled ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880
  14. [ ServiceStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: Directly return. Reason: Invokers from previous router is empty or conditionRouters is empty. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880
  15. [ AppStateRouter (Input: 2) (Current Node Output: 2) (Chain Node Output: 2) Router message: Directly return. Reason: Invokers from previous router is empty or conditionRouters is empty. ] Current Node Output: 172.18.111.187:20880,172.18.111.183:20880
  16. ···
  17. dubbo>

关闭采样的方式:

  1. dubbo>disableRouterSnapshot com.dubbo.*
  2. OK. Found service count: 1
  3. dubbo>

注:采集路由信息会消耗一定的性能,排查完毕后请及时关闭。 参考文档:路由状态命令

最后修改 September 13, 2024: Refactor website structure (#2860) (1a4b998f54b)