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

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.dtcms.com/a/271841.html

相关文章:

  • 前端面试十一之TS
  • 服务器重装后如何“复活”旧硬盘上的 Anaconda 环境?—— 一次完整的排错与恢复记录
  • 计算机学科专业基础综合(408)四门核心课程的知识点总结
  • 微信小程序101~110
  • 以太网基础⑤UDP 协议原理与 FPGA 实现
  • 2025年7月9日学习笔记——模式识别与机器学习——fisher线性回归、感知器、最小二乘法、最小误差判别算法、罗杰斯特回归算法——线性分类器
  • 【TCP/IP】1. 概述
  • AI赋能生活:深度解析与技术洞察
  • LiteHub之文件下载与视频播放
  • 微信小程序控制空调之EMQX服务器安装与配置
  • 重新配置电脑中的环境变量
  • SpringBoot ThreadLocal 全局动态变量设置
  • 机器学习11——支持向量机上
  • 初学者对编译和链接的学习笔记(含预编译详解)
  • 广告匹配策略的智能化之路:人工智能大模型的方法和步骤
  • 多模态大语言模型arxiv论文略读(156)
  • vivo Pulsar 万亿级消息处理实践(3)-KoP指标异常修复
  • 快速上手MongoDB与.NET/C#整合
  • 【AI大模型】LLM模型架构深度解析:BERT vs. GPT vs. T5
  • searxng 对接openweb-UI实现大模型通过国内搜索引擎在线搜索
  • 搜索引擎vs向量数据库:LangChain混合检索架构实战解析
  • 计算机视觉 之 数字图像处理基础
  • 基于 SpringBoot + Vue 的 IT 技术交流和分享平台的设计与实现
  • TCP-与-UDP-协议详解:原理、区别与应用场景全解析
  • 北斗舞动在线监测装置:电力安全的“智慧守护者”
  • SpringMVC @ExceptionHandler 典型用法
  • 了解去中心化金融在现代经济中的作用——安全交易新时代
  • 编写bat文件自动打开chrome浏览器,并通过selenium抓取浏览器操作chrome
  • 双指针-18.四数之和-力扣(LeetCode)
  • linux系统---ISCSI存储服务