官方文档:Apache Dubbo
一、SpringBoot整合Dubbo
1、依赖
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>3.3.0</version>
</dependency>
2、配置
spring:
application:
name: user-service
cloud:
nacos:
discovery:
server-addr: 192.168.111.129:8848 #配置Nacos地址
username: nacos
password: nacos
namespace: public
group: DEFAULT_GROUP
# dubbo配置
dubbo:
application:
name: user-service-dubbo
logger: slf4j
# 配置注册中心
registry:
#address: zookeeper://127.0.0.1:2181
address: nacos://127.0.0.1:8848
username: nacos
password: nacos
protocol:
name: tri
port: 50051
3、启动类
// 启用Dubbo
@EnableDubbo
// 可自定义包扫描路径
@DubboComponentScan
// 启用Nacos注册中心
@EnableDiscoveryClient
@SpringBootApplication
public class UserServiceApplication {
public static void main(String[] args) {
SpringApplication.run(UserServiceApplication.class, args);
}
}
4、定义公共接口
public interface OrderService {
List<String> query(Long userId);
}
5、服务提供者实现接口
import org.apache.dubbo.config.annotation.DubboService;
import show.rewind.dubbo.OrderService;
import java.util.ArrayList;
import java.util.List;
@DubboService
public class OrderServiceImpl implements OrderService {
@Override
public List<String> query(Long userId) {
List<String> orderList = new ArrayList<>();
orderList.add(userId + ":order:" + 1);
orderList.add(userId + ":order:" + 2);
return orderList;
}
}
6、服务消费者调用接口
@RestController
@RequestMapping("/user")
public class UserController {
@DubboReference
private OrderService orderService;
@GetMapping("/get")
public String get() {
List<String> list = orderService.query(1L);
return String.join(",", list);
}
}
二、组件解析
@DubboService
、@DubboReference
与 @EnableDubbo
注解。其中 @DubboService
与 @DubboReference
用于标记 Dubbo 服务,EnableDubbo
启动 Dubbo 相关配置并指定 Spring Boot 扫描包路径。
1、@DubboService
@Service
注解从 3.0 版本开始就已经废弃,改用@DubboService
,以区别于 Spring 的@Service
注解
(1)核心参数
interfaceClass
/interfaceName
作用:指定服务实现的接口类(通常是服务接口的全限定名)。
示例:
@DubboService(interfaceClass = UserService.class) public class UserServiceImpl implements UserService { ... }
version
作用:服务版本号,用于接口多版本灰度发布。
默认值:空字符串。
示例:
@DubboService(version = "1.0.0")
group
作用:服务分组,用于区分同一接口的不同实现(如环境隔离)。
默认值:空字符串。
示例:
java
复制
@DubboService(group = "dev")
(2)服务治理参数
timeout
作用:调用超时时间(单位:毫秒)。
默认值:
-1
(使用全局配置)。示例:
@DubboService(timeout = 5000) // 5秒超时
retries
作用:远程调用失败时的重试次数(不包含第一次调用)。
默认值:
2
(总调用次数为 3)。特殊值:设置为
0
表示不重试。示例:
@DubboService(retries = 3)
loadbalance
作用:负载均衡策略,可选值:
random
(随机)roundrobin
(轮询)leastactive
(最少活跃调用)consistenthash
(一致性哈希)
默认值:
random
。示例:
@DubboService(loadbalance = "roundrobin")
actives
作用:服务提供者最大并发调用数(超过时阻塞等待)。
默认值:
0
(不限制)。示例:
@DubboService(actives = 100)
cluster
作用:集群容错模式,可选值:
failover
(失败自动切换)failfast
(快速失败)failsafe
(失败安全)failback
(失败自动恢复)forking
(并行调用多个服务)
默认值:
failover
。示例:
@DubboService(cluster = "failfast")
(3)高级参数
validation
作用:启用参数校验(需配合 JSR-303 注解,如
@NotNull
)。可选值:
true
/false
。默认值:
false
。示例:
@DubboService(validation = true)
executor
作用:指定服务线程池类型(如
fixed
、cached
)。默认值:使用全局配置。
示例:
@DubboService(executor = "fixed")
weight
作用:服务权重,影响负载均衡概率(数值越大,被调用的概率越高)。
默认值:
-1
(使用全局配置)。示例:
@DubboService(weight = 200)
register
作用:是否将服务注册到注册中心。
默认值:
true
。示例:
@DubboService(register = false) // 仅本地暴露,不注册到注册中心
该参数可用于关联指定的注册中心
dubbo:
application:
name: dubbo-springboot-demo-provider
protocol:
name: tri
port: -1
registry:
id: zk-registry
address: zookeeper://127.0.0.1:2181
通过注解将 service 关联到上文定义的特定注册中心(通过id关联)
@DubboService(registry="zk-registry")
public class DemoServiceImpl implements DemoService {}
(4)协议与注册中心
protocol
作用:指定服务暴露的协议(如
dubbo
、rest
、http
)。默认值:使用全局配置。
示例:
@DubboService(protocol = "rest")
tag
作用:服务标签,用于路由规则匹配。
默认值:空字符串。
示例:
@DubboService(tag = "gray") // 标记为灰度服务
token
作用:启用令牌验证,防止服务被非法调用。
可选值:
true
/false
或指定令牌字符串。示例:
@DubboService(token = "secure-token-123")
(5)其他参数
deprecated
作用:标记服务已过时(调用时会产生警告日志)。
默认值:
false
。示例:
@DubboService(deprecated = true)
dynamic
作用:是否动态注册服务(停机时自动取消注册)。
默认值:
true
。示例:
@DubboService(dynamic = false)
accesslog
作用:是否记录访问日志。
默认值:
false
。示例:
@DubboService(accesslog = true)
三、通信协议
Dubbo 作为一款 RPC 框架内置了高效的 RPC 通信协议,帮助解决服务间的编码与通信问题,目前支持的协议包括:
- triple,基于 HTTP/1、HTTP/2 的高性能通信协议,100% 兼容 gRPC,支持 Unary、Streming 等通信模式;支持发布 REST 风格的 HTTP 服务。
- dubbo,基于 TCP 的高性能私有通信协议,缺点是通用性较差,更适合在 Dubbo SDK 间使用;
- 任意协议扩展,通过扩展 protocol 可以之前任意 RPC 协议,官方生态库提供 JsonRPC、thrift 等支持。
开发者该如何确定使用哪一种协议那? 以下是我们从使用场景、性能、编程易用性、多语言互通等方面对多个主流协议的对比分析:
协议 | 性能 | 网关友好 | 流式通信 | 多语言支持 | 编程API | 说明 |
---|---|---|---|---|---|---|
triple | 高 | 高 | 支持,客户端流、服务端流、双向流 | 支持(Java、Go、Node.js、JavaScript、Rust) | Java Interface、Protobuf(IDL) | 在多语言兼容、性能、网关、Streaming、gRPC 等方面最均衡的协议实现,官方推荐。 |
dubbo | 高 | 低 | 不支持 | 支持(Java、Go) | Java Interface | 性能最高的私有协议,但前端流量接入、多语言支持等成本较高 |
rest | 低 | 高 | 不支持 | 支持 | Java Interface | rest 协议在前端接入、互通等方面具备最高的灵活性,但对比 rpc 存在性能、弱类型等缺点。注意,rest 在 dubbo3 中仅是 triple 协议的一种发布形式 |
注意
自 3.3 版本开始,triple 协议支持以 rest 风格发布标准的 http 服务,因此框架中实际已不存在独立的 rest protocol 扩展实现。只是在文档说明上,我们依然选择将 triple 与 rest 作为独立的协议实现分开讲解,请大家注意。
协议默认值
以下是几个主要协议的具体开发、配置、运行态信息:
协议名称 | 配置值 | 服务定义方式 | 默认端口 | 传输层协议 | 序列化协议 | 是否默认 |
---|---|---|---|---|---|---|
triple | tri | - Java Interface - Protobuf(IDL) | 50051 | HTTP/1、HTTP/2 | Protobuf Binary、Protobuf JSON | 否 |
dubbo | dubbo | - Java Interface | 20880 | TCP | Hessian、Fastjson2、JSON、JDK、Avro、Kryo 等 | 是 |
rest | tri 或 rest | - Java Interface + SpringMVC - Java Interface + JAX-RS | 50051 | HTTP/1、HTTP/2 | JSON | 否 |
注意
考虑到对过往版本的兼容性,当前 Dubbo 各个发行版本均默认使用 dubbo
通信协议。对于新用户而言,我们强烈建议在一开始就明确配置使用 triple
协议。老用户也尽快参考文档 实现协议的平滑迁移。
配置方式:
dubbo:
protocol:
name: dubbo
port: 20880
四、负载均衡
Dubbo 内置了 client-based 负载均衡机制,如下是当前支持的负载均衡算法,结合上文提到的自动服务发现机制,消费端会自动使用 Weighted Random LoadBalance 加权随机负载均衡策略
选址调用。
如果要调整负载均衡算法,以下是 Dubbo 框架内置的负载均衡策略:
算法 | 特性 | 备注 | 配置值 |
---|---|---|---|
Weighted Random LoadBalance | 加权随机 | 默认算法,默认权重相同 | random (默认) |
RoundRobin LoadBalance | 加权轮询 | 借鉴于 Nginx 的平滑加权轮询算法,默认权重相同 | roundrobin |
LeastActive LoadBalance | 最少活跃优先 + 加权随机 | 背后是能者多劳的思想 | leastactive |
Shortest-Response LoadBalance | 最短响应优先 + 加权随机 | 更加关注响应速度 | shortestresponse |
ConsistentHash LoadBalance | 一致性哈希 | 确定的入参,确定的提供者,适用于有状态请求 | consistenthash |
P2C LoadBalance | Power of Two Choice | 随机选择两个节点后,继续选择“连接数”较小的那个节点。 | p2c |
Adaptive LoadBalance | 自适应负载均衡 | 在 P2C 算法基础上,选择二者中 load 最小的那个节点 | adaptive |
全局配置
Dubbo 框架的默认策略是 random
加权随机负载均衡。如果要调整策略,只需要设置 loadbalance
相应取值即可,每种负载均衡策略取值请参见文档最上方表格。
为所有服务调用指定全局配置:
dubbo:
consumer:
loadbalance: roundrobin
接口级配置
可以为每个服务指定不同的负载均衡策略。
在 provider 端设置,作为 consumer 侧默认值
@DubboService(loadbalance = "roundrobin")
public class DemoServiceImpl implements DemoService {}
在 consumer 端设置,具备更高优先级
@DubboReference(loadbalance = "roundrobin")
private DemoService demoService;
方法级配置
也可以指定方法(method)级别的负载均衡策略。
在 Spring Boot 开发模式下,配置 method 级别参数有以下几种方式:
JavaConfig
@Configuration
public class DubboConfiguration {
@Bean
public ServiceBean demoService() {
MethodConfig method = new MethodConfig();
method.setName("sayHello");
method.setLoadbalance("roundrobin");
ServiceBean service = new ServiceBean();
service.setInterface(DemoService.class);
service.setRef(new DemoServiceImpl());
service.addMethod(method)
return service;
}
}
@Autowire
private DemoService demoService;
@Configuration
public class DubboConfiguration {
@Bean
public ReferenceBean demoService() {
MethodConfig method = new MethodConfig();
method.setName("sayHello");
method.setLoadbalance("roundrobin");
ReferenceBean<DemoService> reference = new ReferenceBean<>();
reference.setInterface(DemoService.class);
reference.addMethod(method);
return reference;
}
}
dubbo.properties
dubbo.reference.org.apache.dubbo.samples.api.DemoService.sayHello.loadbalance=roundrobin
一致性哈希配置
默认采用第一个参数作为哈希 key,如果需要切换参数,可以指定 hash.arguments
属性
ReferenceConfig<DemoService> referenceConfig = new ReferenceConfig<DemoService>();
// ... init
Map<String, String> parameters = new HashMap<String, String>();
parameters.put("hash.arguments", "1");
parameters.put("sayHello.hash.arguments", "0,1");
referenceConfig.setParameters(parameters);
referenceConfig.setLoadBalance("consistenthash");
referenceConfig.get();
自适应负载均衡配置
只需要在 consumer 或 provider 端将 loadbalance
设置为 p2c
或者 adaptive
即可,可在此查看 工作原理