【开发】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

三、踩坑记录

简单记录一下踩坑过程,当注册模式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 {
            
        }
    }
}

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

if (MetadataService.isMetadataService(invocation.getServiceName())) {
    return invoker.invoke(invocation);
}

修改后代码为

@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 {
            
        }
    }
}

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

<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-spring-boot-starter</artifactId>
    <version>3.0.8</version>
</dependency>
<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-registry-nacos</artifactId>
    <version>3.0.8</version>
</dependency>

<dependency>
    <groupId>com.alibaba.nacos</groupId>
    <artifactId>nacos-client</artifactId>
    <version>2.1.0</version>
</dependency>
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值