00-Dubbo-原生API开发应用
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 应用的启动入口。ApplicationConfig是name应用名及应用级别的一些全局配置MetricsConfig是protocol、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 服务MethodConfig否name、oninvoke、onreturn、onthrowServiceConfig/ReferenceConfig 内嵌的方法级别配置ArgumentConfig否index、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 version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd modelVersion4.0.0/modelVersion lt;groupIdgt;com.hyqlt;/groupIdgt; lt;artifactIdgt;dubbo-examplelt;/artifactIdgt; lt;versiongt;1.0-SNAPSHOTlt;/versiongt; lt;propertiesgt; lt;maven.compiler.sourcegt;8lt;/maven.compiler.sourcegt; lt;maven.compiler.targetgt;8lt;/maven.compiler.targetgt; lt;project.build.sourceEncodinggt;UTF-8lt;/project.build.sourceEncodinggt; lt;/propertiesgt; lt;dependenciesgt; lt;dependencygt; lt;groupIdgt;org.apache.dubbolt;/groupIdgt; lt;artifactIdgt;dubbolt;/artifactIdgt; lt;versiongt;3.3.6lt;/versiongt; lt;/dependencygt; lt;/dependenciesgt; /project4.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?anyhosttrueapplicationdubbo-provider-demobackgroundfalsebind.ip192.168.247.1bind.port50051deprecatedfalsedubbo2.0.2dynamictrueexecutor-management-modeisolationfile-cachetruegenericfalseinterfacecom.hyq.idl.IOrderServicemethodsgetOrderInfopid33976prefer.serializationhessian2,fastjson2qos.enablefalserelease3.3.6sideprovidertimestamp1787714363451, 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?anyhosttrueapplicationdubbo-provider-demobackgroundfalsebind.ip192.168.247.1bind.port50051deprecatedfalsedubbo2.0.2dynamictrueexecutor-management-modeisolationfile-cachetruegenericfalseinterfacecom.hyq.idl.IUserServicemethodsgetUserNamepid33976prefer.serializationhessian2,fastjson2qos.enablefalserelease3.3.6sideprovidertimestamp1787714364216, dubbo version: 3.3.6, current host: 192.168.247.1启动日志里面会包含两个服务的对外提供的地址tri://192.168.247.1:50051/com.hyq.idl.IUserService?anyhosttrueapplicationdubbo-provider-demobackgroundfalsebind.ip192.168.247.1bind.port50051deprecatedfalsedubbo2.0.2dynamictrueexecutor-management-modeisolationfile-cachetruegenericfalseinterfacecom.hyq.idl.IUserServicemethodsgetUserNamepid33976prefer.serializationhessian2,fastjson2qos.enablefalserelease3.3.6sideprovidertimestamp1787714364216格式协议://ip:端口/接口全类名?keyvaluekeyvalue参数解析anyhosttrue允许任意主机访问服务。该参数表示服务端不限制调用方的来源 IP任何主机都可以发起 RPC 请求。在实际生产环境中如果服务只对内部网络开放建议结合防火墙或网络安全组来限制访问范围避免将服务直接暴露到公网。applicationdubbo-provider-demo当前应用名即提供者应用名称。该名称用于在注册中心、监控中心和日志系统中标识这个提供者应用方便运维人员快速定位问题。多个服务可以共享同一个应用名但建议一个应用名对应一个独立的部署单元。bind.ip192.168.247.1bind.port50051服务实际绑定本机 IP、端口。bind.ip 是服务监听时绑定的网卡地址bind.port 是服务对外提供 RPC 的端口号。这里端口 50051 与前面 ProtocolConfig 中配置的 Triple 协议端口保持一致如果本机有多个网卡可以通过显式指定 bind.ip 来固定服务监听的网卡。deprecatedfalse该服务不废弃。当该参数为 true 时表示当前服务已被标记为废弃调用方在引用该服务时会收到告警提示通常用于服务升级过程中的平滑过渡提醒调用方尽快迁移到新版本服务。dubbo2.0.2dubbo 协议版本号URL 报文协议版本不是框架版本。该参数标识的是 Dubbo 服务之间通信时使用的协议报文版本用于兼容不同版本的 Dubbo 框架之间的通信与当前使用的 Dubbo 框架版本 3.3.6 是两个不同的概念。dynamictrue动态注册服务下线自动从注册中心删除该节点临时节点。当提供者进程正常关闭或异常退出时注册中心会自动移除该服务节点避免调用方继续向已下线的服务发起请求。如果设置为 false则服务节点会作为持久节点保留在注册中心需要手动清理。executor-management-modeisolation线程池隔离模式消费、提供线程池隔离。在该模式下服务提供方处理 RPC 请求的线程池与消费方发起调用的线程池相互独立互不干扰。这样可以避免某一个服务的线程池耗尽后影响其他服务的正常调用提升整体稳定性。file-cachetrue开启本地文件缓存注册中心元数据注册中心宕机本地还能读缓存。开启后提供者会把注册中心的元数据缓存到本地磁盘文件当注册中心出现故障或网络不可达时服务依然可以基于本地缓存继续对外提供服务增强了系统的容错能力。genericfalse不开启泛化调用。泛化调用是指调用方不依赖服务接口的 class 文件通过通用的参数结构来发起调用通常用于网关、测试平台等场景。这里设置为 false表示调用方需要依赖具体的接口定义进行强类型调用。interfacecom.hyq.idl.IUserServiceRPC 接口全类名和路径部分保持一致。该参数指明了当前 URL 对应的服务接口调用方通过该全类名在注册中心找到对应的提供者并完成服务发现和路由。methodsgetUserName接口对外暴露的方法getUserName。这里列出了该服务接口对外提供的所有方法名多个方法之间用逗号分隔。调用方在发起 RPC 请求时需要指定具体的方法名以及对应的参数。pid33976提供者 Java 进程 PID。该参数记录了当前提供者服务的操作系统进程号在排查问题、查看日志或进行性能监控时可以通过 PID 快速定位到对应的 Java 进程。prefer.serializationhessian2,fastjson2优先序列化器备选 hessian2、fastjson2Triple 优先 protobuf这里是备选回退序列化。Triple 协议默认使用 protobuf 作为序列化方式当调用方不支持 protobuf 时会按照这里配置的顺序依次回退到 hessian2、fastjson2保证不同技术栈之间的兼容性。qos.enablefalse关闭 Dubbo QOS 运维端口。QOS 是 Dubbo 提供的运维管理端口可以用于在线查看服务状态、执行运维命令等。这里显式关闭是为了避免在本地开发或测试环境中暴露额外的端口减少安全风险。release3.3.6Dubbo 框架版本 3.3.6。该参数标识了当前提供者使用的 Dubbo 框架版本号便于在服务治理和问题排查时确认版本兼容性。sideprovider标记这是提供者的 URLconsumer 代表消费者 URL。该参数用于区分当前 URL 是提供者注册到注册中心的地址还是消费者订阅的地址在服务治理和路由策略中起到关键作用。timestamp1787714364216服务注册时间戳毫秒。该参数记录了服务注册到注册中心的时间点可以用于排查服务注册延迟、判断服务是否重新注册等问题。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/getOrderInfoheader:tri-service-group dubbo-provider-demotri-protocol-version 1body: [17555555]5、nacos作为注册中心5.1、POM依赖重点是增加了nacos-client包?xml version1.0 encodingUTF-8? project xmlnshttp://maven.apache.org/POM/4.0.0 xmlns:xsihttp://www.w3.org/2001/XMLSchema-instance xsi:schemaLocationhttp://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd modelVersion4.0.0/modelVersion groupIdcom.hyq/groupId artifactIddubbo-example/artifactId version1.0-SNAPSHOT/version properties maven.compiler.source8/maven.compiler.source maven.compiler.target8/maven.compiler.target project.build.sourceEncodingUTF-8/project.build.sourceEncoding /properties dependencies dependency groupIdorg.apache.dubbo/groupId artifactIddubbo/artifactId version3.3.6/version /dependency dependency groupIdcom.alibaba.nacos/groupId artifactIdnacos-client/artifactId version3.2.3/version /dependency dependency groupIdorg.slf4j/groupId artifactIdslf4j-simple/artifactId version1.7.36/version /dependency /dependencies /project5.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‑demoDubbo 服务接口注册记录providers:com.hyq.idl.IOrderService、providers:com.hyq.idl.IUserService应用实例注册详情Dubbo 服务接口注册记录sideprovider // provider 服务提供者 consumer服务消费者applicationdubbo-provider-demo // 提供者应用名interfacecom.hyq.idl.IOrderService //对外暴露的服务全限定接口名methodsgetOrderInfo // 接口对外暴露的方法protocoltri // 协议prefer.serializationhessian2,fastjson2 // 序列化dynamictrue // 动态节点。提供者下线nacos 会自动删除这条注册数据categoryproviders // 分类providers 提供者还有 consumers、configurators、routers6、多注册中心的支持同一个服务提供者把服务注册到多套独立的注册中心集群进程端口不变解决机房隔离、业务隔离、多地域、迁移灰度。案例演示注册到多个nacos服务中以端口号作为区别8848 88506.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); // 多注册中心 ListRegistryConfig 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(结果orderInfoorderInfo); } }6.4、nacos上存储的数据8848服务上有IUserService8850服务上有IUserService、IOrderService7、多协议同一个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); // 指定多个协议 ListProtocolConfig 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 设置重试次数不重试第一个调用retries2 总共最多调用 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到底在干些啥。