dubbo3.0使用
介绍
官方网址:https://dubbo.apache.org/
本文基于springCloud依赖的方式演示相关示例:https://github.com/alibaba/spring-cloud-alibaba/wiki/Dubbo-Spring-Cloud
dubbo示例项目:https://github.com/apache/dubbo-samples
springBoot相关示例:https://github.com/apache/dubbo-spring-boot-project
Apache Dubbo 是一款 RPC 服务开发框架,用于解决微服务架构下的服务治理与通信问题,官方提供了 Java、Golang 等多语言 SDK 实现。使用 Dubbo 开发的微服务原生具备相互之间的远程地址发现与通信能力, 利用 Dubbo 提供的丰富服务治理特性,可以实现诸如服务发现、负载均衡、流量调度等服务治理诉求。Dubbo 被设计为高度可扩展,用户可以方便的实现流量拦截、选址的各种定制逻辑。
变更简述
应用级服务发现
dubbo3.0使用应用级服务发现,但是兼容2.X版本的接口级服务发现
升级参考:https://dubbo.apache.org/zh/overview/tasks/migration/service-discovery-samples/
举例:
如果一个服务有3个实例,接口级服务发现 存放到注册中心的数据条数可能是 实例数 * 接口数,每条数据包含应用名称,接口名称,ip,端口,协议等数据
应用级服务注册则基于实例数,一个服务又多少个实例,注册中心就有几条数据,保存的主要是每个实例的应用名、ip和端口数据
Triple 协议
协议说明
Triple 是 Dubbo3 提出的基于 HTTP2 的开放协议,旨在解决 Dubbo2 私有协议带来的互通性问题。相比于原有 Dubbo2 协议,Triple 有以下优势:
- 原生和 gRPC 协议互通。打通 gRPC 生态,降低从 gRPC 至 Dubbo 的迁移成本。
- 增强多语言生态。避免因 CPP/C#/RUST 等语言的 Dubbo SDK 能力不足导致业务难以选型适配的问题。
- 网关友好。网关无需参与序列化,方便用户从传统的 HTTP 转泛化 Dubbo 调用网关升级至开源或云厂商的 Ingress 方案。
- 完善的异步和流式支持。带来从底层协议到上层业务的性能提升,易于构建全链路异步以及严格保证消息顺序的流式服务。
因为http1.x 协议冗余较多,比如回车符换行符等,而且一个socket连接只能发起一个http请求,所以有了dubbo协议,数据紧凑,支持多路复用,但是dubbo协议没有http通用,triple协议底层基于HTTP2,所以更通用(比如跨语言、跨异构系统实现起来比较方便),而Http2向下兼容http,结构紧凑,支持多路复用,在dubbo3.0中是用Triple作为默认协议
Dubbo3.0跨语言调用
protobuf : 这个再说吧
官方文档 :https://dubbo.apache.org/zh/docs3-v2/java-sdk/quick-start/idl/
配置手册
配置说明 :https://dubbo.apache.org/zh/docs3-v2/java-sdk/reference-manual/config/
dubbo支持通过api,注解,xml配置文件来声明服务和引用服务。
依赖关系说明
spring.cloud.alibaba版本对应关系参考
https://github.com/alibaba/spring-cloud-alibaba/wiki/%E7%89%88%E6%9C%AC%E8%AF%B4%E6%98%8E
可以看到最近的几个版本中已经没有了dubbo版本的对应关系,说明:https://cloud.tencent.com/developer/article/2120216
如果你使用的是支持dubbo的版本,使用如下依赖,这个依赖对应的示例项目地址
https://gitee.com/archguide/spring-cloud-alibaba-dubbo-examples
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
如果是去除了dubbo的版本,或者你想要升级使用dubbo3.0版本,引入依赖如下,
dubbo版本发布: https://dubbo.apache.org/zh/release/java/
此时最新的是版本是3.1.1,引入依赖
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>3.1.1</version>
</dependency>
dubbo基础示例
这里只演示比较核心的代码
1、api项目
避免在客户端和服务端都重复添加相同接口声明代码,一般由服务端将接口定义和接口涉及到的数据对象都统一放到api项目中,但是这个不是必须,你也可以直接在客服端引入对应的接口和dto代码,甚至不需要包名一致,只要大致的数据结构相同即可。
一个纯净的项目,pom中不需要任何依赖,然后在消费者端和服务提供者端都引入api项目依赖,一个示例如下
2、服务提供者示例
依赖
可以在父项目中引入如下依赖进行版本管理
<!-- Apache Dubbo -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-bom</artifactId>
<version>${dubbo.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
服务提供者依赖
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- dubbo示例的 api项目 依赖-->
<dependency>
<groupId>cn.sry1201</groupId>
<artifactId>demo6-dubbo-api</artifactId>
<version>${project.parent.version}</version>
</dependency>
<!-- Dubbo Spring Cloud Starter -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-nacos</artifactId>
</dependency>
<!-- spring cloud 依赖中有 -->
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
</dependency>
启动类
启动类添加@EnableDubbo注解
@SpringBootApplication
@Slf4j
@EnableDubbo
public class DubboProviderApplication {
public static void main(String[] args) {
SpringApplication.run(DubboProviderApplication.class, args);
log.info("{} startup success", "DubboProviderApplication");
}
}
服务注册
@DubboService
public class EchoServiceImpl implements EchoService {
@Override
public String echo(String a) {
return "你好呀";
}
}
配置文件
dubbo:
application:
name: doubbo-consumer
registry:
address: nacos://61.171.5.6:30848
username: nacos
password: nacos
3、服务消费者示例
依赖和启动类
同服务提供者
服务发现
@RestController
@RequestMapping("/echo")
public class EchoController {
@DubboReference
private EchoService echoService;
@GetMapping("/test1")
public String echo(){
String str = echoService.echo("q");
return str;
}
}
配置文件
同服务提供者
4、成功截图
5、问题:
依赖冲途
1、在包含nacos-discovery-spring-boot-starter依赖的时候,没有nacos discovery相关配置时,dubbo指定的配置不生效,会默认以127.0.0.1:9848去获取数据,如果包含nacos discovery时,不太清楚具体情况,未测试
找不到服务,项目启动失败
2、服务提供者未启动,消费者单独启动时会报找不到服务,添加配置
java.lang.IllegalStateException: Failed to check the status of the service cn.sry1201.dubbo.service.EchoService.
dubbo:
application:
name: doubbo-consumer
service-discovery:
migration: FORCE_APPLICATION # APPLICATION_FIRST 多订阅模式(默认)FORCE_APPLICATION 应用级订阅 FORCE_INTERFACE(接口级)
registry:
address: nacos://61.171.5.6:30848
username: nacos
password: nacos
check: false #检测注册中心是否可用,true报错(默认),false忽略
consumer:
check: false #客户端检测服务是否可用,true报错(默认),false忽略
‘
应用级注册
3、服务还是有接口级注册,有多少个接口类,注册多少个服务
官方说明:https://dubbo.apache.org/zh/overview/tasks/migration/service-discovery-samples/
https://dubbo.apache.org/zh/docs3-v2/java-sdk/upgrades-and-compatibility/service-discovery/service-discovery-rule/
服务端配置
dubbo:
application:
name: doubbo-provider
register-mode: instance # all (默认,双注册) instance(应用级注册) service (接口级注册)
registry:
address: nacos://61.171.5.6:30848
username: nacos
password: nacos
客户端配置
当前共存在三种状态,FORCE_INTERFACE(强制接口级),APPLICATION_FIRST(应用级优先)、FORCE_APPLICATION(强制应用级)。
FORCE_INTERFACE:只启用兼容模式下接口级服务发现的注册中心逻辑,调用流量 100% 走原有流程 APPLICATION_FIRST:开启接口级、应用级双订阅,运行时根据阈值和灰度流量比例动态决定调用流量走向 FORCE_APPLICATION:只启用新模式下应用级服务发现的注册中心逻辑,调用流量 100% 走应用级订阅的地址
配置如下
dubbo:
application:
name: doubbo-consumer
service-discovery:
migration: FORCE_APPLICATION # APPLICATION_FIRST 多订阅模式(默认)FORCE_APPLICATION 应用级订阅 FORCE_INTERFACE(接口级)
似乎还有动态配置,这个另说,如果不是需要迁移应该用不上
热部署插件报错
Live reload start error java.net.BindException: Address already in use: JVM_Bind
spring.devtools.livereload.port: 35730 # 热部署插件端口号指定,多个项目都使用热部署,指定一下35729,(默认)
调用超时
org.apache.dubbo.remoting.TimeoutException: Waiting server-side response timeout by scan timer. start time: 2022-11-08 15:20:23.542, end time: 2022-11-08 15:20:24.561, client elapsed: 0 ms, server elapsed: 1019 ms, timeout: 1000 ms, request: Request [id=9, version=2.0.2, twoWay=true, event=false, broken=false, data=RpcInvocation [methodName=echo, parameterTypes=[class java.lang.String]]], channel: /192.168.153.1:14924 -> /192.168.153.1:20881
dubbo:
application:
name: doubbo-consumer
service-discovery:
migration: FORCE_APPLICATION # APPLICATION_FIRST 多订阅模式(默认)FORCE_APPLICATION 应用级订阅 FORCE_INTERFACE(接口级)
registry:
address: nacos://61.171.5.6:30848
username: nacos
password: nacos
group: dubbo-group # 指定分组
parameters: # 扩展参数
"namespace": 748dcaf9-492c-47f9-a4a8-972cccb5f579 # 指定命名空间
check: false #检测注册中心是否可用,true报错(默认),false忽略
consumer:
check: false #客户端检测服务是否可用,true报错(默认),false忽略
timeout: 3000 # 指定超时时间
nacos配置管理界面多出了无用的配置
删除的只剩下一条了
主要是 这个配置 use-as-metadata-center: false
dubbo:
application:
name: doubbo-provider
register-mode: instance # all (默认,双注册) instance(应用级注册) service (接口级注册)
metadata-type: local # 元数据存放在provider 这边
metadata-service-port: 20889
metadata-service-protocol: dubbo
registry:
id: nacos-1 # 如果多个注册中心,@DubboService(registry="nacos-1") 指定服务发现的注册中心
address: nacos://61.171.5.6:30848?registry-type=service # ?registry-type=service 表示仅仅进行应用级服务发现
username: nacos
password: nacos
group: dubbo-group # 指定分组
parameters: # 扩展参数
namespace: 748dcaf9-492c-47f9-a4a8-972cccb5f579 # 指定命名空间
register-consumer-url: true # 是否注册消费者
use-as-metadata-center: false # 作为元数据中心
use-as-config-center: false # 作为配置中心,会有服务信息上传到配置中心,似乎默认是true
应用级服务发现 metadata 传递方式,是以 Provider 视角而言的,Consumer 侧配置无效,可选值有:
* remote - Provider 把 metadata 放到远端注册中心,Consumer 从注册中心获取;
* local - Provider 把 metadata 放在本地,Consumer 从 Provider 处直接获取;
了解到dubbo需要调用服务还需要获取服务的元数据,这个元数据可以存在元数据中心,就nacos而言,使用nacos的配置中心作为元数据中心,如果配置了local(默认),那么consumer会从provider这边获取元数据,但是无语了,已经进行了相关配置,nacos上多余的数据也没了,但是服务调用不通了,报找不到服务。死活找不到原因。
对比前后, metadata-type设置成local和remote还是有区别的,至少nacos上的配置项数量不一样。这样的话建议单独配置元数据中心。具体可以去官网查看元数据中心描述:https://dubbo.apache.org/zh/docs/references/metadata/
6、配置项说明
客户端和服务端配置官网 :https://dubbo.apache.org/zh/docs3-v2/java-sdk/advanced-features-and-usage/performance/simplify-registry-data/
https://dubbo.apache.org/zh/docs/references/xml/
也可以直接进入配置类中查看注释
nacos 配置项
比如就nacos而言,你可能还需要配置group,namespace,以下是服务提供者配置,服务消费者应该大致相同
dubbo:
application:
name: doubbo-provider
register-mode: instance # all (默认,双注册) instance(应用级注册) service (接口级注册)
registry:
address: nacos://61.171.5.6:30848
username: nacos
password: nacos
group: dubbo-group # 指定分组
parameters: # 扩展参数
"namespace": 748dcaf9-492c-47f9-a4a8-972cccb5f579 # 指定命名空间
# config-center:
# address: nacos://61.171.5.6:30848
# metadata-report:
# address: nacos://61.171.5.6:30848
triple协议使用
https://dubbo.apache.org/zh/docs3-v2/java-sdk/reference-manual/protocol/triple/
https://dubbo.apache.org/zh/overview/tasks/migration/migration-triple/
依赖
由于 Triple 协议底层需要依赖 protobuf 协议进行传输,即使定义的服务接口不使用 protobuf 也需要在环境中引入 protobuf 的依赖。
<!-- Triple 协议底层需要依赖 protobuf 协议进行传输 -->
<dependency>
<groupId>com.google.protobuf</groupId>
<artifactId>protobuf-java</artifactId>
</dependency>
<!-- triple -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-rpc-triple</artifactId>
</dependency>
<!-- 基于triple,流式调用支持-->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-common</artifactId>
</dependency>
配置文件
一部分
protocol:
name: tri
port: -1 # 表示随机端口
大致是在配置文件里指定一下协议,然后调用流程和dubbo协议一致,只是多了流式调用的支持,分为客户端流,服务端流,具体就是客服端发送数据或者服务端响应数据可以分多次发送,发送一段,处理一段,响应一段。可能适合数据量大的情况吧,然后就是基于triple协议实现的跨语言和跨平台能力。具体实现再说
其他
dubbo还有其他一些高级特性,https://dubbo.apache.org/zh/docs3-v2/java-sdk/advanced-features-and-usage/
关联信息
- 关联的主题:
- 上一篇:
- 下一篇:
- image: 20221108/1
- 转载自: