dubbo踩坑

记录一下学习dubbo中踩的坑

版本

版本务必要匹配,否则总会出一些问题,目前使用的版本如下:

  • openjdk version 11.0.10

  • SpringBoot: 2.1.6.RELEASE

  • dubbo: 2.7.7

  • dubbo-spring-boot-starter: 2.7.7

  • nacos-client: 1.4.1

  • dubbo-serialization-kryo: 2.7.9

  • com.github.briandilley.jsonrpc4j:jsonrpc4j:1.2.0

    仅在使用http协议时引用。高版本上HttpException访问权限为default

  • org.eclipse.jetty:jetty-servlet

    注意,官网标定版本是6.1.26,但是此版本的groupdId和包名是org.mortbay.jetty

整体基于spring.properties配置

ps: 在此必须骂一下dubbo的文档,dubbo高版本上已经在源码上集成了若干注册中心的代码,但是文档里居然还在要求引入相关的依赖,而且demo的版本还在0.0.2

多协议

官网上只列出了xml下的多协议

经过测试,服务提供者spring配置应该如下

1
2
3
4
5
6
7
8
## 多出的协议写在这里
dubbo.protocols.dubbo.port=20081
dubbo.protocols.http.port=7845
## 以下配置必须写,否则会报错
dubbo.protocol.name=dubbo
dubbo.protocol.port=10022

## 以上配置会启动三个协议,分别是dubbo[10022]、http[7845]、dubbo[20081]

某项服务如果提供了多协议,那么消费者默认都是dubbo协议,暂时没有找到切换的方法

http协议踩坑

在使用http协议时,消费者忘记引入jsonrpc,结果出现找不到服务提供者错误No provider available for the service

经过一天 的排查,问题出现在org.apache.dubbo.registry.integration.RegistryDirectory:429。由于org.apache.dubbo.rpc.protocol.http.HttpProtocol引入了jsonrpc4j的依赖


dubbo里的http协议意思是rpc过程通过http协议传输,对应的接口并不能对web提供,哪怕官网确实写了可以。想要实现需要使用REST协议,但是需要对代码作改动


dubbo-admin 测试不支持http协议,一旦只提供http协议的,测试就会出现服务找不到错误,但是消费者实际使用时没有问题

日志

配置项中务必加上

1
dubbo.application.logger=slf4j

否则 dubbo 不会输出日志

多实现

假设一个接口有多个实现,那么之间必须进行分组,否则只会注册一个实现。

现在我有两个FileStorage的实现类

分别注解如下

1
2
@DubboService( protocol = "http", tag = "minio",group = "minio")
public class MinIOFileStorage implements FileStorage
1
2
@DubboService(protocol = "http",tag = "qn",interfaceClass = FileStorage.class,group = "qn")
public class QiNiuFileStorage implements FileStorage

nacos 显示如下

![2021-04-05 15-11-23屏幕截图](/home/ink/图片/2021-04-05 15-11-23屏幕截图.png)

但是在dubbo-admin中又只显示qn实现,只有一次显示了两个实现

消费者引用如下

1
2
3
4
@DubboReference(group = "minio")
private FileStorage minioFileStorage;
@DubboReference(group = "qn")
private FileStorage qnFileStorage;

测试结果显示,两个变量都是 QiNiuFileStorage 的实现,查看nacos,消费者只订阅了minio

![](/home/ink/图片/2021-04-05 15-13-20屏幕截图.png)

多次测试后发现,此时是dubbo的负载均衡作祟,多个实现轮流调用

测试后修改配置如下

1
2
3
@DubboService( group = "minio")
@Component
public class MinIOFileStorage implements FileStorage
1
2
@DubboService(group = "qn",path = "qnFileStorage")
public class QiNiuFileStorage implements FileStorage
1
2
3
4
@DubboReference(group = "minio")
private FileStorage fileStorage;
@DubboReference(group = "qn")
private FileStorage qnFileStorage;

实际起作用的是path = “qnFileStorage”,怀疑可能是dubbo通过path去寻找对应的实现类,默认情况下path相同,被是为同一实现的不同实例,启用负载。

但是dubbo-admin 仍然只能看到一个实现

多版本

当服务端配置了版本

1
2
dubbo.provider.version=1.0
dubbo.provider.group=dev-third

消费者也必须指定版本

1
2
dubbo.consumer.group=dev-third
dubbo.consumer.version=1.0

文档上注明 不关注版本时可以 写成 *****

但实际上 会出现以下错误

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
[2021-04-11 15:45:02.552] [3.4.1] [DubboSaveMetadataReport-thread-1] [后台] [无] ERROR org.apache.dubbo.metadata.store.nacos.NacosMetadataReport :  [DUBBO] Failed to put consumer metadata org.apache.dubbo.metadata.report.identifier.MetadataIdentifier@2c1e3659;  {init=false, side=consumer, release=2.7.7, logger=slf4j, dubbo=2.0.2, interface=com.bcyunqian.yq.third.api.Bank4Identify, version=*, qos.enable=false, generic=true, timeout=5000, metadata-type=remote, application=service, sticky=false, group=dev-third}, cause: Failed to put org.apache.dubbo.metadata.report.identifier.MetadataIdentifier@2c1e3659 to nacos {"init":"false","side":"consumer","release":"2.7.7","logger":"slf4j","dubbo":"2.0.2","interface":"com.bcyunqian.yq.third.api.Bank4Identify","version":"*","qos.enable":"false","generic":"true","timeout":"5000","metadata-type":"remote","application":"service","sticky":"false","group":"dev-third"}, cause: dataId invalid, dubbo version: 2.7.7, current host: 192.168.101.100
org.apache.dubbo.rpc.RpcException: Failed to put org.apache.dubbo.metadata.report.identifier.MetadataIdentifier@2c1e3659 to nacos {"init":"false","side":"consumer","release":"2.7.7","logger":"slf4j","dubbo":"2.0.2","interface":"com.bcyunqian.yq.third.api.Bank4Identify","version":"*","qos.enable":"false","generic":"true","timeout":"5000","metadata-type":"remote","application":"service","sticky":"false","group":"dev-third"}, cause: dataId invalid
at org.apache.dubbo.metadata.store.nacos.NacosMetadataReport.storeMetadata(NacosMetadataReport.java:210)
at org.apache.dubbo.metadata.store.nacos.NacosMetadataReport.doStoreConsumerMetadata(NacosMetadataReport.java:165)
at org.apache.dubbo.metadata.report.support.AbstractMetadataReport.storeConsumerMetadataTask(AbstractMetadataReport.java:286)
at org.apache.dubbo.metadata.report.support.AbstractMetadataReport.lambda$storeConsumerMetadata$1(AbstractMetadataReport.java:272)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
at java.base/java.lang.Thread.run(Thread.java:834)
Caused by: com.alibaba.nacos.api.exception.NacosException: dataId invalid
at com.alibaba.nacos.client.config.utils.ParamUtils.checkKeyParam(ParamUtils.java:90)
at com.alibaba.nacos.client.config.utils.ParamUtils.checkParam(ParamUtils.java:147)
at com.alibaba.nacos.client.config.NacosConfigService.publishConfigInner(NacosConfigService.java:222)
at com.alibaba.nacos.client.config.NacosConfigService.publishConfig(NacosConfigService.java:121)
at com.alibaba.nacos.client.config.NacosConfigService.publishConfig(NacosConfigService.java:116)
at org.apache.dubbo.metadata.store.nacos.NacosMetadataReport.storeMetadata(NacosMetadataReport.java:204)
... 6 common frames omitted

可以看出 nacos 不支持该特性

多次订阅

在启用了@EnableDubbo以及dubbo.consumer.generic=true的情况下

当同一个接口在不同的地方使用 @DubboReference ,会提示重复引入


dubbo踩坑
http://blog.inkroom.cn/2021/04/04/045R8S.html
作者
inkbox
发布于
2021年4月4日
许可协议