00-Dubbo-原生API开发应用
2026/9/17 23:23:14 网站建设 项目流程

1、前言

在企业级的应用开发的时候,一般都是基于springboot、springcloud框架上使用dubbo,但是Dubbo作为一款RPC框架,Dubbo定义了一套完善的API接口,我们也是可以基于原生API开发Dubbo应用,纯API可以实现的业务场景包括:

  • 轻量RPC Server & Client,通常用于一些应用内、基础组件、中间件等内的简单远程调用场景
  • 微服务应用,不依赖spring的情况下,直接用API开发微服务

2、常用API组件

API 组件全局唯一核心方法或属性说明
DubboBootstrap是(多应用场景除外)start()、stop()DubboBootstrap 实例代表一个 Dubbo 应用,是整个 Dubbo 应用的启动入口。
ApplicationConfigname应用名及应用级别的一些全局配置
MetricsConfigprotocol、prometheus、tracingMetrics、tracing 采集相关配置
ProtocolConfig否。多协议场景服务通过 id 关联id、name、port、serialization、threadpoolRPC 协议端口、序列化协议、运行时行为配置
RegistrtyConfig否。多注册中心场景服务通过 id 关联id、address、protocol、group注册中心实现、地址、订阅等配置
ConfigCenterConfig否。多配置中心场景服务通过 id 关联id、address、protocol、group、namespace配置中心实现、地址、分组隔离等配置
MetadataReportConfig否。多元数据中心场景服务通过 id 关联id、address、protocol、group、namespace元数据中心实现、地址、分组隔离等配置
ProviderConfig参考 ServiceConfig作为多个ServiceConfig的默认值
ConsumerConfig参考 ReferenceConfig作为多个ReferenceConfig的默认值
ServiceConfig- 方法:export()
- 属性: interfaceClass、ref、group、version、timeout、retry
一个 ServiceConfig 实例代表一个 RPC 服务
ReferenceConfig- 方法:refer()
- 属性:interfaceClass、group、version、timeout、retry、cluster、loadbalance
一个 ReferenceConfig 实例代表一个 RPC 服务
MethodConfigname、oninvoke、onreturn、onthrowServiceConfig/ReferenceConfig 内嵌的方法级别配置
ArgumentConfigindex、type、callbackMethodConfig 内嵌的参数级别配置

3、代码和分支说明

代码地址: https://gitee.com/huyanqiu6666/dubbo-example

分支说明
master直连服务调用
nacos增加nacos注册中心
many-registry-nacos多注册中心
many-protocol多协议
load-balance负载均衡
generic-reference泛化
cluster-fail容错机制,快速失败,失败重试等
service-down服务降级

4、轻量RPC调用

4.1、POM依赖

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> &lt;groupId&gt;com.hyq&lt;/groupId&gt; &lt;artifactId&gt;dubbo-example&lt;/artifactId&gt; &lt;version&gt;1.0-SNAPSHOT&lt;/version&gt; &lt;properties&gt; &lt;maven.compiler.source&gt;8&lt;/maven.compiler.source&gt; &lt;maven.compiler.target&gt;8&lt;/maven.compiler.target&gt; &lt;project.build.sourceEncoding&gt;UTF-8&lt;/project.build.sourceEncoding&gt; &lt;/properties&gt; &lt;dependencies&gt; &lt;dependency&gt; &lt;groupId&gt;org.apache.dubbo&lt;/groupId&gt; &lt;artifactId&gt;dubbo&lt;/artifactId&gt; &lt;version&gt;3.3.6&lt;/version&gt; &lt;/dependency&gt; &lt;/dependencies&gt; </project>

4.2、服务端发布

package com.hyq.server; import com.hyq.idl.IOrderService; import com.hyq.idl.IUserService; import com.hyq.idl.impl.OrderServiceImpl; import com.hyq.idl.impl.UserServiceImpl; import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.config.ApplicationConfig; import org.apache.dubbo.config.ProtocolConfig; import org.apache.dubbo.config.bootstrap.DubboBootstrap; import org.apache.dubbo.config.bootstrap.builders.ServiceBuilder; public class ServerMain { public static void main(String[] args) { // 启动服务 ApplicationConfig application = new ApplicationConfig("dubbo-provider-demo"); // group // 关闭qos application.setQosEnable(false); DubboBootstrap.getInstance() .application(application) .protocol(new ProtocolConfig(CommonConstants.TRIPLE, 50051)) // 协议配置 .service(ServiceBuilder.newBuilder() // 发布IUserService服务 .interfaceClass(IUserService.class) .ref(new UserServiceImpl()).build()) .service(ServiceBuilder.newBuilder() // 发布IOrderService的服务 .interfaceClass(IOrderService.class) .ref(new OrderServiceImpl()).build()) .start() .await(); // 阻塞在这块 } }

启动日志:

信息: [DUBBO] [SERVICE_PUBLISH][METADATA_REGISTER] Export dubbo service com.hyq.idl.IOrderService to url tri://192.168.247.1:50051/com.hyq.idl.IOrderService?anyhost=true&application=dubbo-provider-demo&background=false&bind.ip=192.168.247.1&bind.port=50051&deprecated=false&dubbo=2.0.2&dynamic=true&executor-management-mode=isolation&file-cache=true&generic=false&interface=com.hyq.idl.IOrderService&methods=getOrderInfo&pid=33976&prefer.serialization=hessian2,fastjson2&qos.enable=false&release=3.3.6&side=provider&timestamp=1787714363451, dubbo version: 3.3.6, current host: 192.168.247.1 信息: [DUBBO] [SERVICE_PUBLISH][METADATA_REGISTER] Export dubbo service com.hyq.idl.IUserService to url tri://192.168.247.1:50051/com.hyq.idl.IUserService?anyhost=true&application=dubbo-provider-demo&background=false&bind.ip=192.168.247.1&bind.port=50051&deprecated=false&dubbo=2.0.2&dynamic=true&executor-management-mode=isolation&file-cache=true&generic=false&interface=com.hyq.idl.IUserService&methods=getUserName&pid=33976&prefer.serialization=hessian2,fastjson2&qos.enable=false&release=3.3.6&side=provider&timestamp=1787714364216, dubbo version: 3.3.6, current host: 192.168.247.1

启动日志里面会包含两个服务的对外提供的地址:

tri://192.168.247.1:50051/com.hyq.idl.IUserService?anyhost=true&application=dubbo-provider-demo&background=false&bind.ip=192.168.247.1&bind.port=50051&deprecated=false&dubbo=2.0.2&dynamic=true&executor-management-mode=isolation&file-cache=true&generic=false&interface=com.hyq.idl.IUserService&methods=getUserName&pid=33976&prefer.serialization=hessian2,fastjson2&qos.enable=false&release=3.3.6&side=provider&timestamp=1787714364216
格式:协议://ip:端口/接口全类名?key=value&key=value
参数解析:
anyhost=true:允许任意主机访问服务。该参数表示服务端不限制调用方的来源 IP,任何主机都可以发起 RPC 请求。在实际生产环境中,如果服务只对内部网络开放,建议结合防火墙或网络安全组来限制访问范围,避免将服务直接暴露到公网。
application=dubbo-provider-demo:当前应用名,即提供者应用名称。该名称用于在注册中心、监控中心和日志系统中标识这个提供者应用,方便运维人员快速定位问题。多个服务可以共享同一个应用名,但建议一个应用名对应一个独立的部署单元。
bind.ip=192.168.247.1&bind.port=50051:服务实际绑定本机 IP、端口。bind.ip 是服务监听时绑定的网卡地址,bind.port 是服务对外提供 RPC 的端口号。这里端口 50051 与前面 ProtocolConfig 中配置的 Triple 协议端口保持一致,如果本机有多个网卡,可以通过显式指定 bind.ip 来固定服务监听的网卡。
deprecated=false:该服务不废弃。当该参数为 true 时,表示当前服务已被标记为废弃,调用方在引用该服务时会收到告警提示,通常用于服务升级过程中的平滑过渡,提醒调用方尽快迁移到新版本服务。
dubbo=2.0.2:dubbo 协议版本号,URL 报文协议版本,不是框架版本。该参数标识的是 Dubbo 服务之间通信时使用的协议报文版本,用于兼容不同版本的 Dubbo 框架之间的通信,与当前使用的 Dubbo 框架版本 3.3.6 是两个不同的概念。
dynamic=true:动态注册,服务下线自动从注册中心删除该节点(临时节点)。当提供者进程正常关闭或异常退出时,注册中心会自动移除该服务节点,避免调用方继续向已下线的服务发起请求。如果设置为 false,则服务节点会作为持久节点保留在注册中心,需要手动清理。
executor-management-mode=isolation:线程池隔离模式,消费、提供线程池隔离。在该模式下,服务提供方处理 RPC 请求的线程池与消费方发起调用的线程池相互独立,互不干扰。这样可以避免某一个服务的线程池耗尽后影响其他服务的正常调用,提升整体稳定性。
file-cache=true:开启本地文件缓存注册中心元数据,注册中心宕机本地还能读缓存。开启后,提供者会把注册中心的元数据缓存到本地磁盘文件,当注册中心出现故障或网络不可达时,服务依然可以基于本地缓存继续对外提供服务,增强了系统的容错能力。
generic=false:不开启泛化调用。泛化调用是指调用方不依赖服务接口的 class 文件,通过通用的参数结构来发起调用,通常用于网关、测试平台等场景。这里设置为 false,表示调用方需要依赖具体的接口定义进行强类型调用。
interface=com.hyq.idl.IUserService:RPC 接口全类名,和路径部分保持一致。该参数指明了当前 URL 对应的服务接口,调用方通过该全类名在注册中心找到对应的提供者,并完成服务发现和路由。
methods=getUserName:接口对外暴露的方法:getUserName。这里列出了该服务接口对外提供的所有方法名,多个方法之间用逗号分隔。调用方在发起 RPC 请求时,需要指定具体的方法名以及对应的参数。
pid=33976:提供者 Java 进程 PID。该参数记录了当前提供者服务的操作系统进程号,在排查问题、查看日志或进行性能监控时,可以通过 PID 快速定位到对应的 Java 进程。
prefer.serialization=hessian2,fastjson2:优先序列化器,备选 hessian2、fastjson2;Triple 优先 protobuf,这里是备选回退序列化。Triple 协议默认使用 protobuf 作为序列化方式,当调用方不支持 protobuf 时,会按照这里配置的顺序依次回退到 hessian2、fastjson2,保证不同技术栈之间的兼容性。
qos.enable=false:关闭 Dubbo QOS 运维端口。QOS 是 Dubbo 提供的运维管理端口,可以用于在线查看服务状态、执行运维命令等。这里显式关闭,是为了避免在本地开发或测试环境中暴露额外的端口,减少安全风险。
release=3.3.6:Dubbo 框架版本 3.3.6。该参数标识了当前提供者使用的 Dubbo 框架版本号,便于在服务治理和问题排查时确认版本兼容性。
side=provider:标记这是提供者的 URL(consumer 代表消费者 URL)。该参数用于区分当前 URL 是提供者注册到注册中心的地址,还是消费者订阅的地址,在服务治理和路由策略中起到关键作用。
timestamp=1787714364216:服务注册时间戳,毫秒。该参数记录了服务注册到注册中心的时间点,可以用于排查服务注册延迟、判断服务是否重新注册等问题。


4.3、客户端调用

package com.hyq.reference; import com.hyq.idl.IUserService; import org.apache.dubbo.config.bootstrap.builders.ReferenceBuilder; public class ReferenceMain { public static void main(String[] args) { IUserService userService = (IUserService) ReferenceBuilder.newBuilder() .interfaceClass(IUserService.class) // 调用的协议接口(IDL) .url("tri://localhost:50051") // 端到端的服务地址 .build() .get(); String message = userService.getUserName("12333"); // 发起远程调用跟本地调用一样方便 System.out.println(message); } }

4.4、ApiFox调用

请求URL: http://localhost:50051/com.hyq.idl.IOrderService/getOrderInfo
header:
tri-service-group dubbo-provider-demo
tri-protocol-version 1
body: [17555555]

5、nacos作为注册中心

5.1、POM依赖

重点是增加了nacos-client包

<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.hyq</groupId> <artifactId>dubbo-example</artifactId> <version>1.0-SNAPSHOT</version> <properties> <maven.compiler.source>8</maven.compiler.source> <maven.compiler.target>8</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo</artifactId> <version>3.3.6</version> </dependency> <dependency> <groupId>com.alibaba.nacos</groupId> <artifactId>nacos-client</artifactId> <version>3.2.3</version> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-simple</artifactId> <version>1.7.36</version> </dependency> </dependencies> </project>

5.2、服务端发布

增加了registry指定注册中心的地址

package com.hyq.server; import com.hyq.idl.IOrderService; import com.hyq.idl.IUserService; import com.hyq.idl.impl.OrderServiceImpl; import com.hyq.idl.impl.UserServiceImpl; import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.config.ApplicationConfig; import org.apache.dubbo.config.ProtocolConfig; import org.apache.dubbo.config.RegistryConfig; import org.apache.dubbo.config.bootstrap.DubboBootstrap; import org.apache.dubbo.config.bootstrap.builders.ServiceBuilder; public class ServerMain { public static void main(String[] args) { // 启动服务 ApplicationConfig application = new ApplicationConfig("dubbo-provider-demo"); // group // 关闭qos application.setQosEnable(false); DubboBootstrap.getInstance() .application(application) .registry(new RegistryConfig("nacos://127.0.0.1:8848")) // 注册中心配置 .protocol(new ProtocolConfig(CommonConstants.TRIPLE, 50051)) // 协议配置 .service(ServiceBuilder.newBuilder() // 发布IUserService服务 .interfaceClass(IUserService.class) .ref(new UserServiceImpl()).build()) .service(ServiceBuilder.newBuilder() // 发布IOrderService的服务 .interfaceClass(IOrderService.class) .ref(new OrderServiceImpl()).build()) .start() .await(); // 阻塞在这块 } }

5.3、客户端调用

重点是增加了registry的nacos地址配置,去掉了指定的url地址,动态从nacos中获取服务地址

package com.hyq.reference; import com.hyq.idl.IUserService; import org.apache.dubbo.config.RegistryConfig; import org.apache.dubbo.config.bootstrap.builders.ReferenceBuilder; public class ReferenceMain { public static void main(String[] args) { IUserService userService = (IUserService) ReferenceBuilder.newBuilder() .addRegistry(new RegistryConfig("nacos://127.0.0.1:8848")) // 注册中心 .interfaceClass(IUserService.class) // 调用的协议接口(IDL) .build() .get(); String message = userService.getUserName("12333"); // 发起远程调用跟本地调用一样方便 System.out.println("结果:"+message); } }

5.4、nacos服务端存储数据

应用实例注册记录:dubbo‑provider‑demo

Dubbo 服务接口注册记录providers:com.hyq.idl.IOrderServiceproviders:com.hyq.idl.IUserService

应用实例注册详情:

Dubbo 服务接口注册记录:

side=provider // provider 服务提供者 consumer服务消费者
​​​​​application=dubbo-provider-demo // 提供者应用名
interface=com.hyq.idl.IOrderService //对外暴露的服务全限定接口名
methods=getOrderInfo // 接口对外暴露的方法

protocol=tri // 协议
prefer.serialization=hessian2,fastjson2 // 序列化
dynamic=true // 动态节点。提供者下线,nacos 会自动删除这条注册数据
category=providers // 分类:providers = 提供者;还有 consumers、configurators、routers;

6、多注册中心的支持

同一个服务提供者,把服务注册到多套独立的注册中心集群,进程端口不变,解决机房隔离、业务隔离、多地域、迁移灰度。
案例演示注册到多个nacos服务中,以端口号作为区别:8848 8850

6.1、POM依赖

跟4.1一样即可

6.2、服务端发布

IUserService发布的到8848 8850上而IOrderService只发布到8850;
所以在8848上调用IUserService会报没有找到可用的服务

package com.hyq.server; import com.alibaba.nacos.shaded.com.google.common.collect.Lists; import com.hyq.idl.IOrderService; import com.hyq.idl.IUserService; import com.hyq.idl.impl.OrderServiceImpl; import com.hyq.idl.impl.UserServiceImpl; import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.config.ApplicationConfig; import org.apache.dubbo.config.ProtocolConfig; import org.apache.dubbo.config.RegistryConfig; import org.apache.dubbo.config.bootstrap.DubboBootstrap; import org.apache.dubbo.config.bootstrap.builders.ServiceBuilder; import java.util.List; /** * 使用同一注册中心不同端口来区分 */ public class ServerMain { public static void main(String[] args) { // 启动服务 ApplicationConfig application = new ApplicationConfig("dubbo-provider-demo"); // group // 关闭qos application.setQosEnable(false); // 多注册中心 List<RegistryConfig> registryConfigs = Lists.newArrayList(); RegistryConfig beijingRegistryConfig = new RegistryConfig("nacos://127.0.0.1:8848"); registryConfigs.add(beijingRegistryConfig); RegistryConfig shanghaiRegistryConfig = new RegistryConfig("nacos://127.0.0.1:8850"); registryConfigs.add(shanghaiRegistryConfig); DubboBootstrap.getInstance() .application(application) .registries(registryConfigs) // 多注册中心 .protocol(new ProtocolConfig(CommonConstants.TRIPLE, 50051)) // 协议配置 .service(ServiceBuilder.newBuilder() .addRegistries(registryConfigs) // 指定服务发布到那个注册中心,发布多个 .interfaceClass(IUserService.class) // 发布的协议 (IDL接口定义语言) .ref(new UserServiceImpl()) .build()) .service(ServiceBuilder.newBuilder() .addRegistry(shanghaiRegistryConfig) // 指定服务发布到那个注册中心,发布一个 .interfaceClass(IOrderService.class) // 发布的协议 (IDL接口定义语言) .ref(new OrderServiceImpl()) .build()) .start() .await(); // 阻塞在这块 } }

6.3、客户端调用

package com.hyq.reference; import com.hyq.idl.IOrderService; import com.hyq.idl.IUserService; import org.apache.dubbo.config.RegistryConfig; import org.apache.dubbo.config.bootstrap.builders.ReferenceBuilder; public class ReferenceMain { public static void main(String[] args) { RegistryConfig beijingRegistryConfig = new RegistryConfig("nacos://127.0.0.1:8850"); IUserService userService = (IUserService) ReferenceBuilder.newBuilder() .addRegistry(beijingRegistryConfig) // 注册中心,从beijing的注册中心获取数据 .interfaceClass(IUserService.class) // 调用的协议接口(IDL) .build() .get(); String message = userService.getUserName("12333"); // 发起远程调用跟本地调用一样方便 System.out.println("结果:"+message); System.out.println("------------------------"); RegistryConfig registryConfig = new RegistryConfig("nacos://127.0.0.1:8848"); IOrderService orderService = (IOrderService) ReferenceBuilder.newBuilder() .addRegistry(registryConfig) // 注册中心,从beijing的注册中心获取数据 .interfaceClass(IOrderService.class) // 调用的协议接口(IDL) .build() .get(); // 报错:No provider available for the service com.hyq.idl.IOrderService String orderInfo = orderService.getOrderInfo("12333");// 发起远程调用跟本地调用一样方便 System.out.println("结果orderInfo:"+orderInfo); } }

6.4、nacos上存储的数据

8848服务上有IUserService,8850服务上有IUserService、IOrderService

7、多协议

同一个Provider进程监听多个端口,暴露多种通信协议;服务注册到同一个注册中心,一条Provider实例携带多个协议地址;消费者可按需选择协议调用。

7.1、POM依赖

保持不变即可

7.2、服务端发布

服务发布后可以在注册中心nacos上清晰的看到有端口不同多条详情

package com.hyq.server; import com.alibaba.nacos.shaded.com.google.common.collect.Lists; import com.hyq.idl.IOrderService; import com.hyq.idl.IUserService; import com.hyq.idl.impl.OrderServiceImpl; import com.hyq.idl.impl.UserServiceImpl; import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.config.ApplicationConfig; import org.apache.dubbo.config.ProtocolConfig; import org.apache.dubbo.config.RegistryConfig; import org.apache.dubbo.config.bootstrap.DubboBootstrap; import org.apache.dubbo.config.bootstrap.builders.ServiceBuilder; import java.util.List; public class ServerMain { public static void main(String[] args) { // 启动服务 ApplicationConfig application = new ApplicationConfig("dubbo-provider-demo"); // group // 关闭qos application.setQosEnable(false); // 指定多个协议 List<ProtocolConfig> protocolConfigList = Lists.newArrayList(); ProtocolConfig triProtocolConfig = new ProtocolConfig(CommonConstants.TRIPLE, 50051); protocolConfigList.add(triProtocolConfig); ProtocolConfig duooProtocolConfig = new ProtocolConfig(CommonConstants.DUBBO, 40051); protocolConfigList.add(duooProtocolConfig); DubboBootstrap.getInstance() .application(application) .registry(new RegistryConfig("nacos://127.0.0.1:8848")) // 注册中心配置 .protocols(protocolConfigList) // 多协议配置 .service(ServiceBuilder.newBuilder() // 发布IUserService服务 .interfaceClass(IUserService.class) .ref(new UserServiceImpl()).build()) .service(ServiceBuilder.newBuilder() // 发布IOrderService的服务 .interfaceClass(IOrderService.class) .ref(new OrderServiceImpl()).build()) .start() .await(); // 阻塞在这块 } }

7.3、客户端调用

客户端可以按需使用指定协议的服务提供者

package com.hyq.reference; import com.hyq.idl.IUserService; import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.config.RegistryConfig; import org.apache.dubbo.config.bootstrap.builders.ReferenceBuilder; public class ReferenceMain { public static void main(String[] args) { IUserService userService = (IUserService) ReferenceBuilder.newBuilder() .addRegistry(new RegistryConfig("nacos://127.0.0.1:8848")) // 注册中心 .protocol(CommonConstants.DUBBO) // 指定协议 .interfaceClass(IUserService.class) // 调用的协议接口(IDL) .build() .get(); String message = userService.getUserName("12333"); // 发起远程调用跟本地调用一样方便 System.out.println("结果:"+message); } }

7.4、注册中心存储

8、负载均衡

服务端、客户端一般都是集群部署的,在客户端拿到服务端列表的时候会使用某种选择的机制得到一个调用的服务端的地址就称之为负载均衡。简单来说其实就是选取一个调用的服务。比如随机、轮询等方式。
在dubbo中支持全局、接口、方法三个维度配置;优先级是靠的越近的优先级越高,
方法>接口>全局

package com.hyq.reference; import com.alibaba.nacos.shaded.com.google.common.collect.Lists; import com.hyq.idl.IUserService; import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.common.constants.LoadbalanceRules; import org.apache.dubbo.config.MethodConfig; import org.apache.dubbo.config.RegistryConfig; import org.apache.dubbo.config.bootstrap.builders.ReferenceBuilder; public class ReferenceMain { public static void main(String[] args) { // 设置方法级别的负载均衡 MethodConfig methodConfig = new MethodConfig(); methodConfig.setName("getUserName"); methodConfig.setLoadbalance(LoadbalanceRules.ROUND_ROBIN); IUserService userService = (IUserService) ReferenceBuilder.newBuilder() .addRegistry(new RegistryConfig("nacos://127.0.0.1:8848")) // 注册中心 .protocol(CommonConstants.DUBBO) // 指定协议 .interfaceClass(IUserService.class) // 调用的协议接口(IDL) .loadbalance(LoadbalanceRules.RANDOM) // 设置接口级别的负载均衡 .addMethods(Lists.newArrayList(methodConfig)) // 设置方法级别的负载均衡 .build() .get(); String message = userService.getUserName("12333"); // 发起远程调用跟本地调用一样方便 System.out.println("结果:"+message); } }

9、泛化调用

消费者不需要引入服务提供者的接口jar包,直接通过字符串:接口名、方法名、参数类型、参数值调用远程Dubbo服务。
跨语言的调用,没有java接口;网关、测试平台、管理后台不知道提供者接口定义,动态调用dubbo服务;动态脚本、自动化测试平台。

package com.hyq.reference; import com.hyq.idl.IUserService; import org.apache.dubbo.config.ReferenceConfig; import org.apache.dubbo.config.RegistryConfig; import org.apache.dubbo.config.bootstrap.builders.ReferenceBuilder; import org.apache.dubbo.rpc.service.GenericService; /** * 泛化调用 */ public class GenericReferenceMain { public static void main(String[] args) { // 获取代理对象 GenericService genericService = (GenericService)ReferenceBuilder.newBuilder() .addRegistry(new RegistryConfig("nacos://127.0.0.1:8848")) .interfaceName("com.hyq.idl.IUserService") // 接口的全限定名 .generic(true) // 开启泛化调用 .build() .get(); Object result = genericService.$invoke( "getUserName", // 参数1:方法名称 new String[]{"java.lang.String"}, // 参数2:参数类型数组,全类名;String的全类名 java.lang.String new Object[]{"12333"}); // 参数3:入参值数组 System.out.println("泛化调用返回结果:" + result); } }

10、容错机制

在分布式架构下,由原来的本地调用演变成了RPC通信调用,在这过程可能会因为网络波动等原因导致失败,这个时候需要有响应的容错机制,保证业务的安全性。比如失败重试等。

策略名称行为生产常用
failover失败自动切换(默认失败自动重试其他节点;retries 设置重试次数;不重试第一个调用,retries=2 总共最多调用 3 次读接口,幂等查询;写接口慎用,会重复提交
failfast快速失败调用一次失败,立刻抛出异常,不重试写操作、非幂等接口,防止重复请求
failsafe失败安全失败直接吞掉异常,返回 null,不抛错日志、埋点、次要统计,允许丢数据
failback失败自动恢复失败后台记录请求,异步定时重试;消息通知,允许延迟执行
forking并行调用并行调用多个 provider,取第一个成功返回;高可用实时查询,消耗更多资源
available可用实例遍历所有实例,找到第一个可用的直接调用,不重试少用
package com.hyq.reference; import com.alibaba.nacos.shaded.com.google.common.collect.Lists; import com.hyq.idl.IUserService; import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.common.constants.LoadbalanceRules; import org.apache.dubbo.config.MethodConfig; import org.apache.dubbo.config.RegistryConfig; import org.apache.dubbo.config.bootstrap.builders.ReferenceBuilder; import org.apache.dubbo.rpc.cluster.support.FailoverCluster; public class ReferenceMain { public static void main(String[] args) { // 设置方法级别的负载均衡 MethodConfig methodConfig = new MethodConfig(); methodConfig.setName("getUserName"); methodConfig.setLoadbalance(LoadbalanceRules.ROUND_ROBIN); IUserService userService = (IUserService) ReferenceBuilder.newBuilder() .addRegistry(new RegistryConfig("nacos://127.0.0.1:8848")) // 注册中心 .protocol(CommonConstants.DUBBO) // 指定协议 .interfaceClass(IUserService.class) // 调用的协议接口(IDL) .loadbalance(LoadbalanceRules.RANDOM) // 设置接口级别的负载均衡 .cluster(FailoverCluster.NAME) // 容错机制:失败重试 .retries(2) // 重试两次 .timeout(1000) // 超时时间 1秒,没有响应就任务是失败,则会发起重试 .addMethods(Lists.newArrayList(methodConfig)) // 设置方法级别的负载均衡 .build() .get(); String message = userService.getUserName("12333"); // 发起远程调用跟本地调用一样方便 System.out.println("结果:"+message); } }

11、服务降级

降级:牺牲非核心业务,保住主流程;当RPC调用失败(超时、网络异常、提供者全部挂掉),执行本地兜底逻辑返回默认数据,不抛出异常打断主业务。
Dubbo降级底层是Mock机制(本地伪装),属于消费侧能力,Provider不需要写入代码。

两种Mock形式:
fail:先真实远程调用,只有RPC异常失败才执行降级
force:强制降级,完全不发起远程调用,直接走本地Mock逻辑,大促临时屏蔽非核心服务用

降级和容错:
集群容错Cluster:调用失败之后,要怎么处理这次调用(重试、换节点、抛异常),发生在负载均衡选出节点,调用失败之后;
服务降级Mock:容错全部失败之后,给业务返回兜底结果,不抛异常,是最后一道兜底逻辑;
顺序:负载均衡->集群容错->服务降级

package com.hyq.reference; import com.alibaba.nacos.shaded.com.google.common.collect.Lists; import com.hyq.idl.IUserService; import org.apache.dubbo.common.constants.CommonConstants; import org.apache.dubbo.common.constants.LoadbalanceRules; import org.apache.dubbo.config.MethodConfig; import org.apache.dubbo.config.RegistryConfig; import org.apache.dubbo.config.bootstrap.builders.ReferenceBuilder; import org.apache.dubbo.rpc.cluster.support.FailoverCluster; public class ReferenceMain { public static void main(String[] args) { // 设置方法级别的负载均衡 MethodConfig methodConfig = new MethodConfig(); methodConfig.setName("getUserName"); methodConfig.setLoadbalance(LoadbalanceRules.ROUND_ROBIN); IUserService userService = (IUserService) ReferenceBuilder.newBuilder() .addRegistry(new RegistryConfig("nacos://127.0.0.1:8848")) // 注册中心 .protocol(CommonConstants.DUBBO) // 指定协议 .interfaceClass(IUserService.class) // 调用的协议接口(IDL) .loadbalance(LoadbalanceRules.RANDOM) // 设置接口级别的负载均衡 .cluster(FailoverCluster.NAME) // 容错机制:失败重试 .retries(2) // 重试两次 .timeout(1000) // 超时时间 1秒,没有响应就任务是失败,则会发起重试 // .mock("fail:return '服务降级兜底数据'") // fail模式:远程全部失败才降级 .mock("force:return '强制降级'") // force模式:强制降级,不发起任何远程请求,集群容错完全跳过 .addMethods(Lists.newArrayList(methodConfig)) // 设置方法级别的负载均衡 .build() .get(); String message = userService.getUserName("12333"); // 发起远程调用跟本地调用一样方便 System.out.println("结果:"+message); } }

备注:本篇主要是介绍dubbo原生api的基础使用,因为在以前的学习过程中直接上来就是集成了springboot、springCloud使用方式简单,换几个注解使用就可以,导致不了解dubbo到底在干些啥。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询