dubbo icon indicating copy to clipboard operation
dubbo copied to clipboard

provider提供hessian协议服务,consumer订阅该服务的时候,报错。

Open zyxdSTU opened this issue 2 years ago • 4 comments

  • [ ] I have searched the issues of this repository and believe that this is not a duplicate.

Environment

  • Dubbo version: 3.0.9
  • Operating System version: centos
  • Java version: 1.8
  • dubbo-rpc-hessian: 2.7.15

Steps to reproduce this issue

  1. provider注册,hessian协议服务
  2. consumer订阅provider提供的hessian协议服务
  3. 报错Failed to refer invoker for interface:interface org.zjvis.datacenter.service.asset.DownloadAssetService

Expected Behavior

正常订阅hessian协议服务

Actual Behavior

服务端抛出异常

6370 [main] ERROR org.apache.dubbo.registry.client.ServiceDiscoveryRegistryDirectory  -  [DUBBO] Failed to refer invoker for interface:interface org.zjvis.datacenter.service.asset.DownloadAssetService,url:(DefaultServiceInstance{serviceName='datacenter-api-local-asda', host='10.11.33.60', port=20882, enabled=true, healthy=true, metadata={dubbo.metadata-service.url-params={"connections":"1","version":"1.0.0","dubbo":"2.0.2","release":"3.0.9","side":"provider","port":"20881","protocol":"dubbo"}, dubbo.endpoints=[{"port":20882,"protocol":"hessian"},{"port":20881,"protocol":"dubbo"}], dubbo.metadata.revision=ccd36a9506fdfe3585952f41f48bc66b, dubbo.metadata.storage-type=local, timestamp=1657502667429}}, service{name='org.zjvis.datacenter.service.asset.DownloadAssetService',group='null',version='null',protocol='hessian',params={side=provider, metrics.protocol=dubbo, release=3.0.9, methods=downloadDataPattern, logger=slf4j, deprecated=false, dubbo=2.0.2, interface=org.zjvis.datacenter.service.asset.DownloadAssetService, service-name-mapping=true, timeout=10000000, generic=false, metrics.port=20881, application=datacenter-api-local-asda, payload=104857600, hessian.overload.method=true, background=false, dynamic=true, service.filter=metrics, anyhost=true},})null, dubbo version: 3.0.9, current host: 10.11.33.60
java.lang.NullPointerException
	at org.apache.dubbo.common.URL.setProtocol(URL.java:347)
	at org.apache.dubbo.rpc.protocol.hessian.HessianProtocol.doRefer(HessianProtocol.java:136)
	at org.apache.dubbo.rpc.protocol.AbstractProxyProtocol.protocolBindingRefer(AbstractProxyProtocol.java:109)
	at org.apache.dubbo.rpc.protocol.AbstractProtocol.refer(AbstractProtocol.java:133)
	at org.apache.dubbo.rpc.protocol.ProtocolListenerWrapper.refer(ProtocolListenerWrapper.java:77)
	at org.apache.dubbo.qos.protocol.QosProtocolWrapper.refer(QosProtocolWrapper.java:85)
	at org.apache.dubbo.rpc.cluster.filter.ProtocolFilterWrapper.refer(ProtocolFilterWrapper.java:74)
	at org.apache.dubbo.rpc.protocol.ProtocolSerializationWrapper.refer(ProtocolSerializationWrapper.java:52)
	at org.apache.dubbo.rpc.Protocol$Adaptive.refer(Protocol$Adaptive.java)
	at org.apache.dubbo.registry.client.ServiceDiscoveryRegistryDirectory.toInvokers(ServiceDiscoveryRegistryDirectory.java:294)
	at org.apache.dubbo.registry.client.ServiceDiscoveryRegistryDirectory.refreshInvoker(ServiceDiscoveryRegistryDirectory.java:225)
	at org.apache.dubbo.registry.client.ServiceDiscoveryRegistryDirectory.refreshOverrideAndInvoker(ServiceDiscoveryRegistryDirectory.java:153)
	at org.apache.dubbo.registry.client.ServiceDiscoveryRegistryDirectory.notify(ServiceDiscoveryRegistryDirectory.java:147)
	at org.apache.dubbo.registry.client.event.listener.ServiceInstancesChangedListener.addListenerAndNotify(ServiceInstancesChangedListener.java:231)
	at org.apache.dubbo.registry.client.ServiceDiscoveryRegistry.subscribeURLs(ServiceDiscoveryRegistry.java:321)
	at org.apache.dubbo.registry.client.ServiceDiscoveryRegistry.doSubscribe(ServiceDiscoveryRegistry.java:216)
	at org.apache.dubbo.registry.client.ServiceDiscoveryRegistry.subscribe(ServiceDiscoveryRegistry.java:184)
	at org.apache.dubbo.registry.ListenerRegistryWrapper.subscribe(ListenerRegistryWrapper.java:111)
	at org.apache.dubbo.registry.integration.DynamicDirectory.subscribe(DynamicDirectory.java:180)
	at org.apache.dubbo.registry.client.ServiceDiscoveryRegistryDirectory.subscribe(ServiceDiscoveryRegistryDirectory.java:107)
	at org.apache.dubbo.registry.integration.RegistryProtocol.doCreateInvoker(RegistryProtocol.java:570)
	at org.apache.dubbo.registry.integration.InterfaceCompatibleRegistryProtocol.getServiceDiscoveryInvoker(InterfaceCompatibleRegistryProtocol.java:65)
	at org.apache.dubbo.registry.client.migration.MigrationInvoker.refreshServiceDiscoveryInvoker(MigrationInvoker.java:436)
	at org.apache.dubbo.registry.client.migration.MigrationInvoker.migrateToApplicationFirstInvoker(MigrationInvoker.java:244)
	at org.apache.dubbo.registry.client.migration.MigrationRuleHandler.refreshInvoker(MigrationRuleHandler.java:73)
	at org.apache.dubbo.registry.client.migration.MigrationRuleHandler.doMigrate(MigrationRuleHandler.java:57)
	at org.apache.dubbo.registry.client.migration.MigrationRuleListener.onRefer(MigrationRuleListener.java:243)
	at org.apache.dubbo.registry.integration.RegistryProtocol.interceptInvoker(RegistryProtocol.java:535)
	at org.apache.dubbo.registry.integration.RegistryProtocol.doRefer(RegistryProtocol.java:505)
	at org.apache.dubbo.registry.integration.RegistryProtocol.refer(RegistryProtocol.java:487)
	at org.apache.dubbo.rpc.protocol.ProtocolListenerWrapper.refer(ProtocolListenerWrapper.java:74)
	at org.apache.dubbo.qos.protocol.QosProtocolWrapper.refer(QosProtocolWrapper.java:83)
	at org.apache.dubbo.rpc.cluster.filter.ProtocolFilterWrapper.refer(ProtocolFilterWrapper.java:71)
	at org.apache.dubbo.rpc.protocol.ProtocolSerializationWrapper.refer(ProtocolSerializationWrapper.java:52)
	at org.apache.dubbo.rpc.Protocol$Adaptive.refer(Protocol$Adaptive.java)
	at org.apache.dubbo.config.ReferenceConfig.createInvokerForRemote(ReferenceConfig.java:494)
	at org.apache.dubbo.config.ReferenceConfig.createProxy(ReferenceConfig.java:397)
	at org.apache.dubbo.config.ReferenceConfig.init(ReferenceConfig.java:285)
	at org.apache.dubbo.config.ReferenceConfig.get(ReferenceConfig.java:219)
	at org.apache.dubbo.config.utils.SimpleReferenceCache.get(SimpleReferenceCache.java:129)
	at org.apache.dubbo.config.deploy.DefaultModuleDeployer.lambda$referServices$6(DefaultModuleDeployer.java:387)
	at java.util.concurrent.ConcurrentHashMap$ValuesView.forEach(ConcurrentHashMap.java:4707)
	at org.apache.dubbo.config.deploy.DefaultModuleDeployer.referServices(DefaultModuleDeployer.java:367)
	at org.apache.dubbo.config.deploy.DefaultModuleDeployer.start(DefaultModuleDeployer.java:154)
	at org.apache.dubbo.config.spring.context.DubboDeployApplicationListener.onContextRefreshedEvent(DubboDeployApplicationListener.java:111)
	at org.apache.dubbo.config.spring.context.DubboDeployApplicationListener.onApplicationEvent(DubboDeployApplicationListener.java:100)
	at org.apache.dubbo.config.spring.context.DubboDeployApplicationListener.onApplicationEvent(DubboDeployApplicationListener.java:45)
	at org.springframework.context.event.SimpleApplicationEventMulticaster.doInvokeListener(SimpleApplicationEventMulticaster.java:172)
	at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:165)
	at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:139)
	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:403)
	at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:360)
	at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:897)
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.finishRefresh(ServletWebServerApplicationContext.java:162)
	at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:553)
	at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:141)
	at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:747)
	at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:397)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:315)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
	at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215)
	at org.zjvis.datascience.web.DataScienceWebMain.main(DataScienceWebMain.java:54)

个人分析

HessianProtocol.doRefer方法中会调用

return (T) hessianProxyFactory.create(serviceType, url.setProtocol("http").toJavaURL(), Thread.currentThread().getContextClassLoader())

其中url.setProtocol("http").toJavaURL()会报NPE错误 主要是因为,url是InstanceAddressUrl的实例, 其urlAddress变量为空, 而url.setProtocol会引用urlAddress变量

卡很久了,有没有大佬来解决一下这个问题。

zyxdSTU avatar Jul 11 '22 06:07 zyxdSTU

这个项目看起来是 3.0.0 的应用级的服务发现与 2.7.x 版本的协议结合使用。 InstanceAddressUrl#setProtocol 确实会抛出空指针异常。 有两个方法可以解决一下你的问题:

  1. InstanceAddressUrl 重写 URL#setProtocol 方法,支持可以修改 protocol 属性。
  2. url.setProtocol("http").toJavaURL() 这部分可以手动拼接一个 http 协议的 java.net.URL

haoyann avatar Jul 12 '22 03:07 haoyann

  1. 可以强制走接口级先饶过
  2. setProtocol 方法会在 https://github.com/apache/dubbo/pull/10256 中修复
  3. hessian 协议兼容版 jar 会在https://github.com/apache/dubbo-spi-extensions/pull/125 中提供

AlbumenJ avatar Jul 12 '22 03:07 AlbumenJ

  1. 可以强制走接口级先饶过
  2. setProtocol 方法会在 Fix wildcard match #10256 中修复
  3. hessian 协议兼容版 jar 会在Add rpc and serialization implmentations dubbo-spi-extensions#125 中提供

目前强制走接口级别,会出现consumer 订阅不了hessian协议服务的问题。所以还是等修复把。

zyxdSTU avatar Jul 12 '22 13:07 zyxdSTU

@zyxdSTU 都已经合并,验证一下是否还有这个问题。

CrazyHZM avatar Jul 15 '22 06:07 CrazyHZM

Has been fixed in the latest 3.0.11 release.

chickenlj avatar Sep 02 '22 02:09 chickenlj