[apache/dubbo]The "rest protocol"'s purpose in Dubbo 3.1.x? 新增加了提供 rest protocol 的意义是?

2024-06-24 354 views
1

当我从3.0.9升级到3.1.0后,启动项目时发现以下报错:

2022-09-06 11:08:17.323 [main] ERROR o.a.d.r.client.ServiceDiscoveryRegistryDirectory - Unsupported protocol rest in notified url: DefaultServiceInstance{serviceName='sys-service', host='192.168.1.55', port=20001, enabled=true, healthy=true, metadata={preserved.register.source=SPRING_CLOUD}}, null from registry 【REGISTRY IP ADDRESS】 to consumer 192.168.1.55, supported protocol: [dubbo, injvm, mock, registry, service-discovery-registry, tri]
java.lang.IllegalStateException: Unsupported protocol rest in notified url: DefaultServiceInstance{serviceName='sys-service', host='192.168.1.55', port=20001, enabled=true, healthy=true, metadata={preserved.register.source=SPRING_CLOUD}}, null from registry 【REGISTRY IP ADDRESS】 to consumer 192.168.1.55, supported protocol: [dubbo, injvm, mock, registry, service-discovery-registry, tri]
    at org.apache.dubbo.registry.client.ServiceDiscoveryRegistryDirectory.toInvokers(ServiceDiscoveryRegistryDirectory.java:300)
    at org.apache.dubbo.registry.client.ServiceDiscoveryRegistryDirectory.refreshInvoker(ServiceDiscoveryRegistryDirectory.java:251)
    at org.apache.dubbo.registry.client.ServiceDiscoveryRegistryDirectory.refreshOverrideAndInvoker(ServiceDiscoveryRegistryDirectory.java:179)
    at org.apache.dubbo.registry.client.ServiceDiscoveryRegistryDirectory.notify(ServiceDiscoveryRegistryDirectory.java:173)
    at org.apache.dubbo.registry.client.event.listener.ServiceInstancesChangedListener.addListenerAndNotify(ServiceInstancesChangedListener.java:235)
    at org.apache.dubbo.registry.client.ServiceDiscoveryRegistry.subscribeURLs(ServiceDiscoveryRegistry.java:325)
    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:124)
    at org.apache.dubbo.registry.integration.RegistryProtocol.doCreateInvoker(RegistryProtocol.java:571)
    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:536)
    at org.apache.dubbo.registry.integration.RegistryProtocol.doRefer(RegistryProtocol.java:506)
    at org.apache.dubbo.registry.integration.RegistryProtocol.refer(RegistryProtocol.java:488)
    at org.apache.dubbo.qos.protocol.QosProtocolWrapper.refer(QosProtocolWrapper.java:80)
    at org.apache.dubbo.rpc.protocol.ProtocolListenerWrapper.refer(ProtocolListenerWrapper.java:74)
    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:600)
    at org.apache.dubbo.config.ReferenceConfig.createProxy(ReferenceConfig.java:441)
    at org.apache.dubbo.config.ReferenceConfig.init(ReferenceConfig.java:295)
    at org.apache.dubbo.config.ReferenceConfig.get(ReferenceConfig.java:227)
    at org.apache.dubbo.config.utils.SimpleReferenceCache.get(SimpleReferenceCache.java:129)
    at org.apache.dubbo.config.deploy.DefaultModuleDeployer.lambda$referServices$6(DefaultModuleDeployer.java:383)
    at java.base/java.util.concurrent.ConcurrentHashMap$ValuesView.forEach(ConcurrentHashMap.java:4780)
    at org.apache.dubbo.config.deploy.DefaultModuleDeployer.referServices(DefaultModuleDeployer.java:363)
    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:176)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.invokeListener(SimpleApplicationEventMulticaster.java:169)
    at org.springframework.context.event.SimpleApplicationEventMulticaster.multicastEvent(SimpleApplicationEventMulticaster.java:143)
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:421)
    at org.springframework.context.support.AbstractApplicationContext.publishEvent(AbstractApplicationContext.java:378)
    at org.springframework.context.support.AbstractApplicationContext.finishRefresh(AbstractApplicationContext.java:938)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:586)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:147)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:734)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:408)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:308)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1306)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1295)
    at cc.uncarbon.module.SaasApiApplication.main(SaasApiApplication.java:10)

然而端口20001是下游微服务的HTTP端口

跟踪代码后我发现: v7gM3F.md.png

provider的配置文件中并没有主动设置 rest 协议,这个应该是注册到注册中心时主动添加的。3.1.0版本的feature公告中好像没有发现用法,请指教

回答

4

这个是应用级服务发现与 Spring Cloud 互通的特性。 这个功能生效的前提是当前初始化的接口的应用名在注册中心存在对应的 Spring Cloud 服务。(如 org.apache.DemoService 接口对应 demo-application 应用名,注册中心存在通过 Spring Cloud 注册的 demo-application 应用) Dubbo 会按照 Spring Cloud 的处理方式读取这部分的服务信息,载入到对应所有接口上。

6

这个异常检测到不支持 rest 协议后回自动忽略这个地址,但是在 3.0 升级到应用级服务发现之后如果存在和 Spring cloud 同名的应用且提供的功能是不一样的最好需要重命名下,否则很容易出现调用错的问题。从日志中看应用名应该都是sys-service

例子:Dubbo 发布了 demo-application 这个应用,Spring Cloud 也发布了demo-application 这个服务,Spring Cloud 通过 Feign 或者 restTemplate 调用的时候只会识别 demo-application 这个应用,最终流量会错误地调用到 Dubbo 上来(如果这不是预期)

2

谢谢大佬的解答,经过试验比较 3.0.113.1.0 版本后可能理解了这个设计

sys-service 使用了 spring-boot-starter-web,启动后将自身注册到 Spring Cloud 注册中心(我使用的是 Nacos),端口为 HTTP 端口,protocol=rest 而 dubbo 也用 sys-service 的名头注册到了 Nacos 上,端口为另一个,protocol=dubbo

上游从注册中心拉取后能正确处理 protocol=dubbo,而处理protocol=rest则会抛出异常(未引入相应支持扩展)

(这里留一个疑问,是否引入 rest 扩展后,dubbo 可以只使用类似 Feign 的 HTTP RPC,而完全不使用 dubbo 主打的 dubbo/triple 协议二进制 RPC?)

通过取消引入 spring-boot-starter-web,使用其他方法 hold 住主线程后,再次启动未出现该异常。

如果没有其他需要订正和为后来者补充的话,烦请关闭该issue。

6

Dubbo 作为服务端可以发布 rest 服务,客户端支持所有标准 rest 协议支持的 SDK(Dubbo、Feign、okhttp、restTemplate 等)、Dubbo 也可以作为客户端消费发布了标准 rest 协议的服务,服务端支持所有标准 rest server(Dubbo、spring web、tomcat、jetty等)

1

了解了,原来现在 dubbo 也可以支持 HTTP 的 RPC 了呀

现在还得尝试解决引入 spring-boot-starter-actuator 探针后,需要 web 监听,又不想自动以 rest 协议注册到 Nacos 上……

(如果没有其他需要订正和为后来者补充的话,烦请关闭该issue。)

3

换个应用名就行了

7

=. = 还真的可以 spring.cloud.nacos.discovery.service=${spring.application.name}-rest

谢谢!

(如果没有其他需要订正和为后来者补充的话,烦请直接关闭该issue。)

1

能不换spring.cloud.nacos.discovery.service 这个参数吗?改了这个参数,影响比较大的呀。为啥我改了dubbo的application.name。也不行呢?