本文目录导读:

下面是一个基于 Apache Dubbo 的完整案例,包含服务接口定义、服务提供者实现、服务消费者调用,以及必要的配置和启动方式,这个案例使用 Spring Boot + Dubbo + ZooKeeper 作为注册中心。
系统架构概览
┌─────────────┐ Dubbo RPC ┌──────────────┐
│ 消费者 │ ─────────────→ │ 提供者 │
│ (Consumer) │ │ (Provider) │
└─────────────┘ └──────────────┘
│ │
│ ┌─────────────┐ │
└──────→ │ ZooKeeper │ ←──────┘
│ (注册中心) │
└─────────────┘
公共接口模块 (dubbo-api)
创建一个Maven项目,只包含接口定义。
UserService.java
package com.example.dubbo.api;
import java.io.Serializable;
// 用户实体
public class User implements Serializable {
private Long id;
private String name;
private String email;
// 无参构造(必须)
public User() {}
// 全参构造
public User(Long id, String name, String email) {
this.id = id;
this.name = name;
this.email = email;
}
// getter/setter 省略
public Long getId() { return id; }
public void setId(Long id) { this.id = id; }
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public String getEmail() { return email; }
public void setEmail(String email) { this.email = email; }
@Override
public String toString() {
return "User{id=" + id + ", name='" + name + "', email='" + email + "'}";
}
}
UserService.java (接口)
package com.example.dubbo.api;
public interface UserService {
User getUserById(Long id);
String register(User user);
}
服务提供者 (dubbo-provider)
使用Spring Boot,实现上述接口并暴露为Dubbo服务。
pom.xml 核心依赖:
<dependencies>
<!-- Dubbo Spring Boot 启动器 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>3.2.0</version>
</dependency>
<!-- ZooKeeper 注册中心客户端 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-zookeeper</artifactId>
<version>3.2.0</version>
</dependency>
<!-- 公共接口模块 -->
<dependency>
<groupId>com.example</groupId>
<artifactId>dubbo-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
<!-- Spring Boot Web (可选) -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
application.yml 配置:
server:
port: 8081
dubbo:
application:
name: dubbo-provider
registry:
address: zookeeper://127.0.0.1:2181
protocol:
name: dubbo
port: 20880
scan:
base-packages: com.example.dubbo.provider
服务实现类:
package com.example.dubbo.provider;
import com.example.dubbo.api.User;
import com.example.dubbo.api.UserService;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.stereotype.Component;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicLong;
@DubboService // 关键注解:将服务暴露为 Dubbo 服务
@Component
public class UserServiceImpl implements UserService {
private final ConcurrentHashMap<Long, User> userStore = new ConcurrentHashMap<>();
private final AtomicLong idGenerator = new AtomicLong(1);
@Override
public User getUserById(Long id) {
System.out.println("[Provider] 查询用户ID: " + id);
return userStore.get(id);
}
@Override
public String register(User user) {
Long newId = idGenerator.getAndIncrement();
user.setId(newId);
userStore.put(newId, user);
System.out.println("[Provider] 注册用户: " + user);
return "注册成功,用户ID: " + newId;
}
}
启动类:
package com.example.dubbo.provider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
System.out.println("=== Dubbo Provider 启动成功 ===");
}
}
服务消费者 (dubbo-consumer)
调用提供者暴露的服务。
application.yml 配置:
server:
port: 8082
dubbo:
application:
name: dubbo-consumer
registry:
address: zookeeper://127.0.0.1:2181
protocol:
name: dubbo
port: 20881
消费者调用服务:
package com.example.dubbo.consumer;
import com.example.dubbo.api.User;
import com.example.dubbo.api.UserService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class UserController {
@DubboReference // 关键注解:注入远程服务代理
private UserService userService;
@GetMapping("/getUser/{id}")
public String getUser(@PathVariable Long id) {
User user = userService.getUserById(id);
return user != null ? user.toString() : "用户不存在 ID: " + id;
}
@GetMapping("/register")
public String register() {
// 注册一个新用户
User user = new User(null, "张三", "zhangsan@example.com");
return userService.register(user);
}
}
启动类:
package com.example.dubbo.consumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}
运行与测试
环境准备
- 启动 ZooKeeper 于本地
0.0.1:2181(默认端口)。
启动顺序
# 1. 启动提供者 (端口 8081) mvn spring-boot:run -pl dubbo-provider # 2. 启动消费者 (端口 8082) mvn spring-boot:run -pl dubbo-consumer
测试调用
# 注册用户
curl http://localhost:8082/register
# 输出:注册成功,用户ID: 1
# 查询用户
curl http://localhost:8082/getUser/1
# 输出:User{id=1, name='张三', email='zhangsan@example.com'}
关键注解与原理说明
| 注解/组件 | 作用 |
|---|---|
@DubboService |
将服务实现暴露为 Dubbo 远程服务 |
@DubboReference |
引用远程服务,自动注入代理对象 |
dubbo.registry |
配置注册中心地址(ZooKeeper/Nacos 等) |
dubbo.protocol |
配置 RPC 协议(默认 dubbo 协议,端口 20880) |
dubbo.scan.base-packages |
扫描包,自动发现 @DubboService 类 |
高级特性扩展(可选)
负载均衡策略
dubbo:
consumer:
loadbalance: roundrobin # 轮询
# 可选:random(随机)、leastactive(最少活跃)、consistenthash(一致性哈希)
超时与重试
@DubboReference(timeout = 3000, retries = 2) private UserService userService;
多注册中心 / 多协议
dubbo:
registry:
- address: zookeeper://127.0.0.1:2181
id: zk1
- address: nacos://127.0.0.1:8848
id: nacos1
protocol:
- name: dubbo
port: 20880
- name: rest
port: 8083
就是一个完整的 Dubbo 案例,如果还需要更多细节(如配置 Nacos 注册中心、使用 JSON 序列化、集成 Spring Cloud),可以随时告诉我!