当前位置: 首页 > ds >正文

Apache Dubbo实战:JavaSDK使用

文章目录

  • 一、写在前面
  • 二、基于zookeeper:快速创建dubbo应用
    • 1、maven包(客户端+服务端)(注意spring版本)
    • 2、application.yml 配置文件(客户端+服务端)
    • 3、定义公共接口
    • 4、启动类添加注解@EnableDubbo
    • 5、服务端
    • 6、客户端
    • 7、启动试试吧
    • 8、拓展:使用 Java Config 代替注解
  • 三、拓展配置
    • 1、注册中心
    • 2、版本与分组
    • 3、传递调用参数
    • 4、泛化调用
    • 5、泛化实现
    • 6、Filter过滤器
  • 附:Dubbo 支持的 Spring Boot Starter 清单

一、写在前面

官方文档:https://cn.dubbo.apache.org/zh-cn/overview/

概念介绍部分就不多做介绍了,看官方文档吧。
本文实践为主,从头到尾梳理Dubbo使用的细节。

二、基于zookeeper:快速创建dubbo应用

1、maven包(客户端+服务端)(注意spring版本)

    <dependencyManagement><dependencies><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-bom</artifactId><version>3.3.0</version><type>pom</type><scope>import</scope></dependency></dependencies></dependencyManagement>
        <dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-starter</artifactId></dependency><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-zookeeper-spring-boot-starter</artifactId></dependency>

2、application.yml 配置文件(客户端+服务端)

dubbo:application:# 客户端和服务端要不一样,客户端:dubbo-springboot-demo-consumername: dubbo-springboot-demo-providerprotocol:name: tri# 随机端口port: -1registry:id: zk-registryaddress: zookeeper://127.0.0.1:2181

3、定义公共接口

package com.demo.springbootdemo;public interface DemoService {String sayHello(String name);}

4、启动类添加注解@EnableDubbo

import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
// @EnableDubbo 注解必须配置,否则将无法加载 Dubbo 注解定义的服务,@EnableDubbo 可以定义在主类上
@EnableDubbo

5、服务端

import org.apache.dubbo.config.annotation.DubboService;// 定义好 Dubbo 服务接口后,提供服务接口的实现逻辑,并用 @DubboService 注解标记,就可以实现 Dubbo 的服务暴露
// 支持很多参数
// @DubboService(registry="zk-registry") 可以手动选择注册中心(通过id关联)
// @DubboService(version = "1.0.0", group = "dev", timeout = 5000)
// @DubboService(methods = {@Method(name = "sayHello", timeout = 5000)}) // 指定某个方法超时时间
@DubboService
public class DemoServiceImpl implements DemoService {@Overridepublic String sayHello(String name) {return "Hello " + name;}
}

6、客户端

import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.boot.CommandLineRunner;
import org.springframework.stereotype.Component;@Component
public class Consumer implements CommandLineRunner {// scope="remote" is used to force mock remote service call// 也有很多参数// @DubboReference(version = "1.0.0", group = "dev", timeout = 5000)@DubboReference(scope = "remote")private DemoService demoService;@Overridepublic void run(String... args) throws Exception {String result = demoService.sayHello("world");System.out.println("Receive result ======> " + result);}
}

7、启动试试吧

8、拓展:使用 Java Config 代替注解

注意,Java Config 是 DubboService 或 DubboReference 的替代方式,对于有复杂配置需求的服务建议使用这种方式。

@Configuration
public class ProviderConfiguration {@Beanpublic ServiceConfig demoService() {ServiceConfig service = new ServiceConfig();service.setRegistry("zk-registry");return service;}
}
@Configuration
public class ProviderConfiguration {@Beanpublic ServiceBean demoService() {ServiceBean service = new ServiceBean();service.setInterface(DemoService.class);service.setRef(new DemoServiceImpl());service.setGroup("dev");service.setVersion("1.0.0");Map<String, String> parameters = new HashMap<>();service.setParameters(parameters);return service;}
}

三、拓展配置

1、注册中心

# application.yml
dubboregistryaddress: zookeeper://localhost:2181# zk认证,可以不配置username: hellopassword: 1234

多级注册中心:
对于所有的 Service 服务,向所有全局默认注册中心注册服务地址。
对于所有的 Reference 服务,从所有全局默认注册中心订阅服务地址。

# application.yml (Spring Boot)
dubboregistriesbeijingRegistryaddress: zookeeper://localhost:2181shanghaiRegistryaddress: zookeeper://localhost:2182# 设置默认全局的注册中心
# application.yml (Spring Boot)
dubboregistriesbeijingRegistryaddress: zookeeper://localhost:2181default: trueshanghaiRegistryaddress: zookeeper://localhost:2182default: false# 可以在开发调试的过程中,设置本地启动的只注册在本地zk,并且调用测试环境的dubbo服务。
# 防止自己的服务注册到测试环境
dubbo:registries:#仅在开发时启用private:id: private# register: true:服务提供者会将服务注册到这个注册中心。# subscribe: false:服务消费者不会从这个注册中心订阅服务。register: truesubscribe: falseaddress: zookeeper://127.0.0.1:2181public:id: publicprotol: zookeeper# register: false:服务提供者不会将服务注册到这个注册中心。# subscribe: true:服务消费者会从这个注册中心订阅服务。register: falsesubscribe: trueaddress: zookeeper://test.zk.com:2181

2、版本与分组

Dubbo服务中,接口并不能唯一确定一个服务,只有 接口+分组+版本号 的三元组才能唯一确定一个服务。

当同一个接口针对不同的业务场景、不同的使用需求或者不同的功能模块等场景,可使用服务分组来区分不同的实现方式。同时,这些不同实现所提供的服务是可并存的,也支持互相调用。

当接口实现需要升级又要保留原有实现的情况下,即出现不兼容升级时,我们可以使用不同版本号进行区分。

@DubboService(group = "group1", version = "1.0")
public class DevelopProviderServiceV1 implements DevelopService{@Overridepublic String invoke(String param) {StringBuilder s = new StringBuilder();s.append("ServiceV1 param:").append(param);return s.toString();}
}@DubboService(group = "group2", version = "2.0")
public class DevelopProviderServiceV2 implements DevelopService{@Overridepublic String invoke(String param) {StringBuilder s = new StringBuilder();s.append("ServiceV2 param:").append(param);return s.toString();}
}
// 客户端指定 分组和版本号
@DubboReference(group = "demo")
private DemoService demoService;@DubboReference(group = "demo2")
private DemoService demoService2;//group值为*,标识匹配任意服务分组
@DubboReference(group = "*")
private DemoService demoService2;@DubboReference(group = "group1", version = "1.0")
private DevelopService developService;@DubboReference(group = "group2", version = "2.0")
private DevelopService developServiceV2;

3、传递调用参数

// 客户端传递参数
RpcContext.getClientAttachment().setAttachment("index", "1"); // 隐式传参,后面的远程调用都会隐式将这些参数发送到服务器端,类似cookie,比如用于框架集成
xxxService.xxx(); // 远程调用
// ...
// 服务端,读取调用参数
public class XxxServiceImpl implements XxxService {public void xxx() {// 获取客户端隐式传入的参数,比如用于框架集成String index = RpcContext.getServerAttachment().getAttachment("index");}
}

参数透传问题
请注意!setAttachment 设置的 KV 对,在完成下面一次远程调用会被清空,即多次远程调用要多次设置!这一点与 Dubbo2 中的行为是不一致的!
比如,对于 Dubbo2 而言,在 A 端设置的参数,调用 B 以后,如果 B 继续调用了 C,原来在 A 中设置的参数也会被带到 C 端过去(造成参数污染的问题)。对于 Dubbo3,B 调用 C 时的上下文是干净的,不会包含最开始在 A 中设置的参数。
Dubbo3 提供的了支持参数透传的能力。通过实现以下 SPI 用户可以自行指定需要透传的参数,select 的结果(可以从 RpcClientAttachment 获取当前所有参数)将作为需要透传的键值对传递到下一跳,如果返回 null 则表示不透传参数。

@SPI
public interface PenetrateAttachmentSelector {/*** Select some attachments to pass to next hop.* These attachments can fetch from {@link RpcContext#getServerAttachment()} or user defined.** @return attachment pass to next hop*/Map<String, Object> select();}

4、泛化调用

文档:https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/tasks/framework/generic/

泛化调用适用于老版本 dubbo 通信协议,如果您使用的是 3.3 及之后版本的 triple 协议,请直接使用 triple 自带的 http application/json 能力直接发起服务调用

泛化调用(客户端泛化调用)是指在调用方没有服务提供方 API(SDK)的情况下,对服务方进行调用,并且可以正常拿到调用结果。调用方没有接口及模型类元,知道服务的接口的全限定类名和方法名的情况下,可以通过泛化调用调用对应接口。

private GenericService genericService;public static void main(String[] args) throws Exception {ApplicationConfig applicationConfig = new ApplicationConfig();applicationConfig.setName("generic-call-consumer");RegistryConfig registryConfig = new RegistryConfig();registryConfig.setAddress("zookeeper://127.0.0.1:2181");ReferenceConfig<GenericService> referenceConfig = new ReferenceConfig<>();referenceConfig.setInterface("org.apache.dubbo.samples.generic.call.api.HelloService");applicationConfig.setRegistry(registryConfig);referenceConfig.setApplication(applicationConfig);referenceConfig.setGeneric("true");// do not wait for result, 'false' by defaultreferenceConfig.setAsync(true);referenceConfig.setTimeout(7000);genericService = referenceConfig.get();
}public static void invokeSayHello() throws InterruptedException {Object result = genericService.$invoke("sayHello", new String[]{"java.lang.String"}, new Object[]{"world"});CountDownLatch latch = new CountDownLatch(1);CompletableFuture<String> future = RpcContext.getContext().getCompletableFuture();future.whenComplete((value, t) -> {System.err.println("invokeSayHello(whenComplete): " + value);latch.countDown();});System.err.println("invokeSayHello(return): " + result);latch.await();
}

5、泛化实现

文档:https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/tasks/framework/more/generic-impl/

泛接口实现方式主要用于服务器端没有 API 接口及模型类元的情况,参数及返回值中的所有 POJO 均用 Map 表示,通常用于框架集成,比如:实现一个通用的远程服务 Mock 框架,可通过实现 GenericService 接口处理所有服务请求。

使用场景
注册服务: 服务提供者在服务注册表中注册服务,例如 Zookeeper,服务注册表存储有关服务的信息,例如其接口、实现类和地址。
部署服务: 服务提供商将服务部署在服务器并使其对消费者可用。
调用服务: 使用者使用服务注册表生成的代理调用服务,代理将请求转发给服务提供商,服务提供商执行服务并将响应发送回消费者。
监视服务:提供者和使用者可以使用 Dubbo 框架监视服务,允许他们查看服务的执行情况,并在必要时进行调整。

6、Filter过滤器

package org.apache.dubbo.samples.extensibility.filter.provider;import org.apache.dubbo.rpc.Filter;
import org.apache.dubbo.rpc.Result;
import org.apache.dubbo.rpc.Invoker;
import org.apache.dubbo.rpc.Invocation;
import org.apache.dubbo.rpc.RpcException;
import org.apache.dubbo.rpc.AsyncRpcResult;public class AppendedFilter implements Filter {@Overridepublic Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {Result result= invoker.invoke(invocation);// Obtain the returned valueResult appResponse = ((AsyncRpcResult) result).getAppResponse();// Appended valueappResponse.setValue(appResponse.getValue()+"'s customized AppendedFilter");return result;}
}

SPI配置:
resources/META-INF/dubbo/org.apache.dubbo.rpc.Filter文件中添加如下配置:
appended=org.apache.dubbo.samples.extensibility.filter.provider.AppendedFilter

配置文件:
resources/application.properties文件中添加如下配置,激活刚才的自定义 Filter 实现:

# Apply AppendedFilter
dubbo.provider.filter=appended

除了通过配置激活 Filter 实现之外,还可以通过为实现类增加 @Activate 注解,以在满足某些条件时自动激活 Filter 实现,如:
@Activate(group=“provider”)
public class AppendedFilter implements Filter {}
这个 Filter 实现将在 Provider 提供者端自动被激活。

附:Dubbo 支持的 Spring Boot Starter 清单

官方文档:https://cn.dubbo.apache.org/zh-cn/overview/mannual/java-sdk/reference-manual/config/spring/spring-boot/#starter%E5%88%97%E8%A1%A8

以下是一些 dubbo-spring-boot-starter 版本对应的 SpringBoot、JDK 依赖:
版本 兼容 Spring Boot 范围
3.3.x [1.x ~ 3.x)
3.2.x [1.x ~ 3.x)
3.1.x [1.x ~ 2.x)
2.7.x [1.x ~ 2.x)

其他组件starter:
以下是 Dubbo 官方社区提供的 starter 列表(3.3.0+ 版本),方便在 Spring Boot 应用中快速使用:
dubbo-spring-boot-starter,管理 dubbo 核心依赖,用于识别 application.properties 或 application.yml 中 dubbo. 开头的配置项,扫描 @DubboService 等注解。
dubbo-spring-boot-starter3,管理 dubbo 核心依赖,与 dubbo-spring-boot-starter 相同,支持 spring boot 3.2 版本。
dubbo-nacos-spring-boot-starter,管理 nacos-client 等依赖,使用 Nacos 作为注册中心、配置中心时引入。
dubbo-zookeeper-spring-boot-starter,管理 zookeeper、curator 等依赖,使用 Zookeeper 作为注册中心、配置中心时引入(Zookeeper server 3.4 及以下版本使用)。
dubbo-zookeeper-curator5-spring-boot-starter,管理 zookeeper、curator5 等依赖,使用 Zookeeper 作为注册中心、配置中心时引入。
dubbo-sentinel-spring-boot-starter,管理 sentinel 等依赖,使用 Sentinel 进行限流降级时引入。
dubbo-seata-spring-boot-starter,管理 seata 等依赖,使用 Seata 作为分布式事务解决方案时引入。
dubbo-observability-spring-boot-starter,加入该依赖将自动开启 Dubbo 内置的 metrics 采集,可用于后续的 Prometheus、Grafana 等监控系统。
dubbo-tracing-brave-spring-boot-starter,管理 brave/zipkin、micrometer 等相关相关依赖,使用 Brave/Zipkin 作为 Tracer,将 Trace 信息 export 到 Zipkin。
dubbo-tracing-otel-otlp-spring-boot-starter,管理 brave/zipkin、micrometer 等相关相关依赖,使用 OpenTelemetry 作为 Tracer,将 Trace 信息 export 到 OTlp Collector。
dubbo-tracing-otel-zipkin-spring-boot-starter,管理 brave/zipkin、micrometer 等相关相关依赖,使用 OpenTelemetry 作为 Tracer,将 Trace 信息 export 到 Zipkin。

http://www.xdnf.cn/news/15242.html

相关文章:

  • 动态物体滤除算法
  • MyBatis-Plus 中使用 Wrapper 自定义 SQL
  • Linux C 文件基本操作
  • 【oscp】超长攻击链vulhub靶机,TommyBoy1dot0
  • 登录为图片验证时,selenium通过token直接进入页面操作
  • ResolvableType 解密Java泛型反射
  • 【会员专享数据】2013-2024年我国省市县三级逐月SO₂数值数据(Shp/Excel格式)
  • 深入拆解Spring核心思想之一:IoC
  • 北京-4年功能测试2年空窗-报培训班学测开-第四十七天
  • 常见射频电路板工艺流程
  • Spring Boot项目中大文件上传的高级实践与性能优化
  • 打破技术债困境:从“保持现状”到成为变革的推动者
  • 机器学习11——支持向量机上
  • 【博主亲测可用】PS2025最新版:Adobe Photoshop 2025 v26.8.1 激活版(附安装教程)
  • C++交叉编译工具链制作以及QT交叉编译环境配置
  • Windows系统DLL、运行库、DirectX等DLL丢失等异常状态
  • 【保姆级喂饭教程】GitLab创建用户规范,分支开发规范,提交日志规范
  • 【实战总结】WMIC在HW行动中的4类关键应用
  • 01-RabbitMQ消息队列
  • 通过vue如何利用 Three 绘制 简单3D模型(源码案例)
  • 【Pandas】pandas DataFrame from_records
  • TCP 保活(KeepAlive)机制详解
  • 在mac m1基于llama.cpp运行deepseek
  • 前端面试十一之TS
  • QPC框架中状态机的设计优势和特殊之处
  • 【Pandas】pandas DataFrame from_dict
  • 数据结构 顺序表(1)
  • iOS Widget 开发-7:TimelineProvider 机制全解析:构建未来时间线
  • 在Docker中运行macOS的超方便体验!
  • macOS 上安装 Miniconda + Conda-Forge