Dubbo
是什么?
- Apache Dubbo 是一款高性能、轻量级的 RPC(远程过程调用)框架,最初由阿里巴巴开源,用于解决微服务间的通信问题。
- 与 OpenFeign 类似,但 Dubbo 更专注于 高性能、低延迟的远程调用(基于 Netty 和 NIO),适合复杂的企业级分布式场景。
核心特性
- 服务注册与发现:通过注册中心(如 ZooKeeper、Nacos)管理服务提供者和消费者。
- 负载均衡:内置多种策略(随机、轮询、最少活跃调用等),类似 LoadBalancer。
- 容错机制:支持失败重试、快速失败、熔断等(类似 Sentinel 的部分功能)。
- 协议支持 :默认使用 Dubbo 协议(二进制序列化,性能高),也支持 HTTP、gRPC 等。
- 服务治理:提供路由规则、动态配置、服务降级等能力。
对比 OpenFeign
特性 | Dubbo | OpenFeign |
---|---|---|
协议 | 自定义二进制协议 | HTTP(RESTful) |
性能 | 更高(Netty 底层) | 基于 HTTP,稍逊 |
适用场景 | 内部服务高频调用 | 跨语言、兼容 REST 规范 |
举个例子,发布文章送积分,一个是文章模块,一个是积分模块,还有个api模块。
下面通过一个完整的示例,演示如何使用 Dubbo 实现「发布文章送积分」的分布式业务场景。假设系统分为三个模块:
- article-service(文章服务)
- points-service(积分服务)
- api-gateway(API 网关,提供 HTTP 接口)
1. 项目结构
markdown
dubbo-demo/
├── api-module/ # 公共API模块(定义接口和DTO)
│ ├── ArticleService.java # 文章服务接口
│ ├── PointsService.java # 积分服务接口
│ └── dto/ # 数据传输对象
├── article-service/ # 文章服务实现
│ └── ArticleServiceImpl.java
├── points-service/ # 积分服务实现
│ └── PointsServiceImpl.java
└── api-gateway/ # HTTP网关(Spring Boot)
└── ArticleController.java
2. 关键代码实现
2.1 公共API模块(api-module)
定义 Dubbo 服务接口和 DTO,供其他模块依赖。
java
// ArticleService.java - 文章服务接口
public interface ArticleService {
void publishArticle(ArticleDTO article);
}
// PointsService.java - 积分服务接口
public interface PointsService {
void addPoints(Long userId, int points);
}
// ArticleDTO.java - 数据传输对象
@Data
public class ArticleDTO implements Serializable {
private Long id;
private String title;
private String content;
private Long authorId;
}
2.2 积分服务(points-service)
实现积分逻辑,暴露 Dubbo 服务。
java
// PointsServiceImpl.java
@Service // Spring Bean
@DubboService // 暴露Dubbo服务(Dubbo 3.0+注解)
public class PointsServiceImpl implements PointsService {
@Override
public void addPoints(Long userId, int points) {
System.out.printf("[积分服务] 用户 %d 增加 %d 积分\n", userId, points);
// 实际业务:更新数据库积分表...
}
}
2.3 文章服务(article-service)
调用积分服务,实现发布文章逻辑。
java
// ArticleServiceImpl.java
@Service
@DubboService
public class ArticleServiceImpl implements ArticleService {
@DubboReference // 引用远程积分服务
private PointsService pointsService;
@Override
public void publishArticle(ArticleDTO article) {
System.out.printf("[文章服务] 发布文章: %s\n", article.getTitle());
// 1. 保存文章到数据库...
// 2. 调用积分服务赠送积分
pointsService.addPoints(article.getAuthorId(), 10); // 送10积分
}
}
2.4 API网关(api-gateway)
提供 HTTP 接口,内部调用 Dubbo 服务。
java
// ArticleController.java
@RestController
public class ArticleController {
@DubboReference
private ArticleService articleService;
@PostMapping("/articles")
public String publishArticle(@RequestBody ArticleDTO article) {
articleService.publishArticle(article);
return "文章发布成功";
}
}
3. 配置说明
3.1 注册中心配置(以 Nacos 为例)
yaml
# article-service 和 points-service 的 application.yml
dubbo:
application:
name: article-service # 或 points-service
registry:
address: nacos://127.0.0.1:8848 # Nacos地址
protocol:
name: dubbo
port: 20880 # 默认Dubbo协议端口
3.2 依赖配置(Maven)
xml
<!-- 所有模块需添加Dubbo依赖 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>
<!-- Nacos注册中心 -->
<dependency>
<groupId>com.alibaba.nacos</groupId>
<artifactId>nacos-client</artifactId>
<version>2.2.2</version>
</dependency>
4. 运行流程
-
启动注册中心 :
先启动 Nacos(bin/startup.sh
)。 -
启动服务提供者 :
启动points-service
和article-service
,服务会自动注册到 Nacos。 -
启动API网关 :
启动api-gateway
,通过 HTTP 接口对外提供服务。 -
测试调用 :
发送 POST 请求到网关:bashcurl -X POST http://localhost:8080/articles \ -H "Content-Type: application/json" \ -d '{"title":"Dubbo实战","content":"...","authorId":123}'
-
输出结果 :
ini[文章服务] 发布文章: Dubbo实战 [积分服务] 用户 123 增加 10 积分
5. 关键设计点
- 服务解耦 :
- 文章服务不直接操作积分数据库,通过 RPC 调用积分服务。
- 事务一致性 :
- 如需保证"发布文章+送积分"的事务一致性,可集成 Seata (通过
@GlobalTransactional
注解)。
- 如需保证"发布文章+送积分"的事务一致性,可集成 Seata (通过
- 容错处理 :
-
在
@DubboReference
中配置重试策略和熔断规则:java@DubboReference(retries = 2, cluster = "failfast") private PointsService pointsService;
-
通过这个例子,可以清晰看到 Dubbo 如何实现跨服务的透明化调用。如果需要进一步扩展(如超时控制、服务分组),只需调整 Dubbo 的配置注解即可。