• Dubbo3注册为应用级时报错“No provider available for the service XXX”



    Dubbo3注册为应用级时,Nacos注册中心看到注册服务服务和订阅列表均正常,但是实际调用时报错“No provider available for the service XXX”

    Dubbo3注册模式介绍

    dubbo3共有三种provider服务注册模式,分别为 interface(接口级)、instance(应用级)、all,默认是all(双注册,兼容模式)
    大概配置如下

    dubbo:
      application:
        name: ${spring.application.name}
        #provider注册模式,可选值 interface(接口级)、instance(应用级)、all,默认是all(双注册)
        register-mode: instance
        metadata-service-port: -1
        #consumer服务发现模式
        service-discovery:
          # FORCE_INTERFACE,只消费接口级地址,如无地址则报错,单订阅 2.x 地址
          # APPLICATION_FIRST,智能决策接口级/应用级地址,双订阅
          # FORCE_APPLICATION,只消费应用级地址,如无地址则报错,单订阅 3.x 地址
          migration: FORCE_APPLICATION
      registry:
        address: nacos://localhost:8848?namespace=my_local
      protocol:
        port: -1
      consumer:
        check: false
      provider:
        filter: dubboExceptionFilter,-exception
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    踩坑记录

    简单记录一下踩坑过程,当注册模式dubbo.application.register-mode=all双注册时可以正常调用,注册模式都改为应用级注册时dubbo.application.register-mode=instance调用报错“No provider available for the service XXX”

    最终排查导致这个报错的原因是项目中自定义的日志traceId传递filter中使用了RpcContext.getContext().isProviderSide()这行代码报错NullPointException导致Consumer端拉取Provider端接口元数据失败,最终导致调用时报错“No provider available for the service XXX”

    原来代码:

    @Activate(group = {CommonConstants.PROVIDER, CommonConstants.CONSUMER}, order = MDCTraceUtils.FILTER_ORDER)
    public class DubboTraceFilter implements Filter {
        
        @Override
        public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        	// 使用应用级时,这行代码会报错 NullPointException
            boolean isProviderSide = RpcContext.getContext().isProviderSide();
            //服务提供者逻辑
            if (isProviderSide) {
                
            } else { //服务消费者逻辑
                
            }
            try {
                return invoker.invoke(invocation);
            } finally {
                
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    在这个代码中加了一行判断,如果时内置元数据拉取服务MetadataService时,跳过当前Filter

    if (MetadataService.isMetadataService(invocation.getServiceName())) {
        return invoker.invoke(invocation);
    }
    
    • 1
    • 2
    • 3

    修改后代码为

    @Activate(group = {CommonConstants.PROVIDER, CommonConstants.CONSUMER}, order = MDCTraceUtils.FILTER_ORDER)
    public class DubboTraceFilter implements Filter {
        
        @Override
        public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
    		// 如果是内置元数据服务则跳过filter,否则走下面的会报错,导致元数据拉取失败,最终导致No provider错误
            if (MetadataService.isMetadataService(invocation.getServiceName())) {
                return invoker.invoke(invocation);
            }
            boolean isProviderSide = RpcContext.getContext().isProviderSide();
            //服务提供者逻辑
            if (isProviderSide) {
                
            } else { //服务消费者逻辑
                
            }
            try {
                return invoker.invoke(invocation);
            } finally {
                
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    以上代码基于dubbo-3.0.8,nacos-2.1.0调试

    <dependency>
        <groupId>org.apache.dubbogroupId>
        <artifactId>dubbo-spring-boot-starterartifactId>
        <version>3.0.8version>
    dependency>
    <dependency>
        <groupId>org.apache.dubbogroupId>
        <artifactId>dubbo-registry-nacosartifactId>
        <version>3.0.8version>
    dependency>
    
    <dependency>
        <groupId>com.alibaba.nacosgroupId>
        <artifactId>nacos-clientartifactId>
        <version>2.1.0version>
    dependency>
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
  • 相关阅读:
    通过配置文件修改docker容器端口映射
    剑指Offer 36.二叉搜索树与双向链表 中序遍历
    CAD最常用的快捷键大全来啦
    vue3.2 导出pdf文件或表格数据
    刷题之路:1196 - 【入门】递归版拐角I题解
    算法 有效括号序列-(栈+哈希)
    Go语言快速入门篇(一):转义字符、注释说明、代码规范
    Linux下安装Redis详细教程 (附安装包)
    MT2041 三角形的个数
    智能合约漏洞,BEVO 代币损失 4.5 万美元攻击事件分析
  • 原文地址:https://blog.csdn.net/UberSoldier/article/details/126768710