Dubbo + Nacos 完整示例项目
1. 项目介绍
本项目是一个基于 Spring Boot + Dubbo + Nacos 的完整示例,展示了如何使用 Nacos 作为服务注册中心和配置中心,结合 Dubbo 实现远程服务调用。
2. 技术栈
| 技术 | 版本 | 用途 |
|---|---|---|
| Spring Boot | 2.7.18 | 基础框架 |
| Dubbo | 3.2.7 | 服务治理框架 |
| Nacos | 2.2.3 | 服务注册中心和配置中心 |
| Java | 8+ | 开发语言 |
3. 项目结构
dubbo-nacos-example/ # 父项目
├── dubbo-api/ # 公共接口模块
│ └── src/main/java/com/example/api/UserService.java # 用户服务接口
├── dubbo-provider/ # 服务提供者模块
│ └── src/main/java/com/example/provider/ # 服务实现
├── dubbo-consumer/ # 服务消费者模块
│ └── src/main/java/com/example/consumer/ # 服务调用
└── pom.xml # 父项目依赖管理
4. 快速开始
4.1 启动 Nacos 服务端
-
下载 Nacos Server 2.2.3:https://github.com/alibaba/nacos/releases
-
解压并启动 Nacos:
bash# Linux/Mac ./bin/startup.sh -m standalone # Windows bin\startup.cmd -m standalone -
访问 Nacos 控制台:http://localhost:8848/nacos
- 默认用户名/密码:nacos/nacos
4.2 构建项目
bash
# 在项目根目录执行
mvn clean install
4.3 启动服务提供者
bash
# 进入服务提供者目录
cd dubbo-provider
# 启动服务
mvn spring-boot:run
4.4 启动服务消费者
bash
# 进入服务消费者目录
cd dubbo-consumer
# 启动服务
mvn spring-boot:run
4.5 测试服务调用
访问 http://localhost:8081/consumer/getUser?id=1,查看调用结果。
5. 详细实现
5.1 公共接口模块 (dubbo-api)
5.1.1 UserService.java
java
package com.example.api;
/**
* 用户服务接口
*/
public interface UserService {
/**
* 根据ID获取用户信息
* @param id 用户ID
* @return 用户信息
*/
User getUser(Long id);
}
5.1.2 User.java
java
package com.example.api;
import java.io.Serializable;
/**
* 用户实体类
* 注意:Dubbo 传输的对象必须实现 Serializable 接口
*/
public class User implements Serializable {
private static final long serialVersionUID = 1L;
private Long id;
private String username;
private String email;
private Integer age;
// 构造方法、getter和setter
// 省略...
}
5.2 服务提供者模块 (dubbo-provider)
5.2.1 依赖配置 (pom.xml)
xml
<dependencies>
<!-- Spring Boot 基础依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<!-- Dubbo 依赖 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<!-- Nacos 注册中心依赖 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-nacos</artifactId>
</dependency>
<!-- 公共接口依赖 -->
<dependency>
<groupId>com.example</groupId>
<artifactId>dubbo-api</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
5.2.2 服务实现 (UserServiceImpl.java)
java
package com.example.provider;
import com.example.api.User;
import com.example.api.UserService;
import org.apache.dubbo.config.annotation.DubboService;
import org.springframework.stereotype.Service;
/**
* 用户服务实现类
* @DubboService 注解:将服务注册到 Dubbo 注册中心
*/
@DubboService
@Service
public class UserServiceImpl implements UserService {
/**
* 根据ID获取用户信息
* 模拟数据库查询,实际项目中应调用数据库
*/
@Override
public User getUser(Long id) {
// 模拟数据库查询
User user = new User();
user.setId(id);
user.setUsername("User" + id);
user.setEmail("user" + id + "@example.com");
user.setAge(20 + (int) (id % 10));
return user;
}
}
5.2.3 配置文件 (application.yml)
yaml
server:
port: 8080 # 服务提供者端口
spring:
application:
name: dubbo-provider # 服务名称
# Dubbo 配置
dubbo:
application:
name: dubbo-provider
id: dubbo-provider
registry:
address: nacos://localhost:8848 # Nacos 注册中心地址
username: nacos
password: nacos
protocol:
name: dubbo # 协议名称
port: 20880 # 服务暴露端口
scan:
base-packages: com.example.provider # 扫描 Dubbo 服务实现类
# Nacos 配置
nacos:
config:
server-addr: localhost:8848
username: nacos
password: nacos
5.2.4 启动类 (ProviderApplication.java)
java
package com.example.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 started successfully!");
}
}
5.3 服务消费者模块 (dubbo-consumer)
5.3.1 依赖配置 (pom.xml)
xml
<dependencies>
<!-- Spring Boot Web 依赖 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- Dubbo 依赖 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<!-- Nacos 注册中心依赖 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-registry-nacos</artifactId>
</dependency>
<!-- 公共接口依赖 -->
<dependency>
<groupId>com.example</groupId>
<artifactId>dubbo-api</artifactId>
<version>${project.version}</version>
</dependency>
</dependencies>
5.3.2 服务调用 (UserController.java)
java
package com.example.consumer;
import com.example.api.User;
import com.example.api.UserService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
/**
* 用户服务消费者控制器
*/
@RestController
public class UserController {
/**
* Dubbo 服务引用
* @DubboReference 注解:引用 Dubbo 服务
*/
@DubboReference(
check = false, // 启动时不检查服务是否可用
retries = 3, // 调用失败重试次数
timeout = 5000 // 调用超时时间
)
private UserService userService;
/**
* 获取用户信息
* @param id 用户ID
* @return 用户信息或错误提示
*/
@GetMapping("/consumer/getUser")
public Object getUser(@RequestParam Long id) {
try {
// 调用远程服务
User user = userService.getUser(id);
return user;
} catch (Exception e) {
// 异常处理
return "Error: " + e.getMessage();
}
}
}
5.3.3 配置文件 (application.yml)
yaml
server:
port: 8081 # 服务消费者端口
spring:
application:
name: dubbo-consumer # 服务名称
# Dubbo 配置
dubbo:
application:
name: dubbo-consumer
id: dubbo-consumer
registry:
address: nacos://localhost:8848 # Nacos 注册中心地址
username: nacos
password: nacos
protocol:
name: dubbo
port: 20881 # 消费者端口
consumer:
check: false # 启动时不检查服务是否可用
# Nacos 配置
nacos:
config:
server-addr: localhost:8848
username: nacos
password: nacos
5.3.4 启动类 (ConsumerApplication.java)
java
package com.example.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);
System.out.println("Dubbo Consumer started successfully!");
}
}
6. 测试验证
6.1 查看服务注册
- 启动 Nacos 控制台:http://localhost:8848/nacos
- 点击左侧菜单 "服务管理" -> "服务列表"
- 可以看到
com.example.api.UserService服务已注册,提供者数量为 1
6.2 调用服务
-
启动服务提供者和服务消费者
-
预期结果:
json{ "id": 1, "username": "User1", "email": "user1@example.com", "age": 21 }
6.3 测试异常情况
-
停止服务提供者
-
预期结果:
Error: Failed to invoke remote method: getUser, provider: dubbo://192.168.1.100:20880/com.example.api.UserService?anyhost=true&application=dubbo-provider&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&interface=com.example.api.UserService&metadata-type=remote&methods=getUser&pid=12345&release=3.2.7&side=provider×tamp=1234567890&version=1.0.0, cause: The service [com.example.api.UserService] not found.
7. 核心配置说明
7.1 Dubbo 核心配置
| 配置项 | 说明 | 默认值 |
|---|---|---|
dubbo.application.name |
应用名称 | - |
dubbo.registry.address |
注册中心地址 | - |
dubbo.protocol.name |
协议名称 | dubbo |
dubbo.protocol.port |
服务暴露端口 | 20880 |
dubbo.scan.base-packages |
扫描服务实现类的包路径 | - |
dubbo.consumer.check |
启动时是否检查服务可用性 | true |
dubbo.consumer.retries |
调用失败重试次数 | 0 |
dubbo.consumer.timeout |
调用超时时间 | 1000 |
7.2 Nacos 核心配置
| 配置项 | 说明 | 默认值 |
|---|---|---|
nacos.config.server-addr |
Nacos 服务器地址 | - |
nacos.config.username |
Nacos 用户名 | nacos |
nacos.config.password |
Nacos 密码 | nacos |
8. 注意事项
- 确保 Nacos 服务端已启动,并且配置的地址、用户名、密码正确
- 服务提供者和服务消费者的
dubbo.registry.address配置必须指向同一个 Nacos 服务端 - 服务接口必须实现
Serializable接口,否则无法在网络中传输 - 生产环境中应根据实际情况调整
timeout、retries等参数 - 建议开启 Nacos 配置中心,将 Dubbo 配置集中管理
9. 扩展建议
- 添加配置中心:使用 Nacos 配置中心管理 Dubbo 配置
- 添加监控:集成 Dubbo Admin 或 SkyWalking 进行服务监控
- 添加熔断机制:集成 Sentinel 实现服务熔断和限流
- 添加日志:集成 ELK 或 Loki 进行日志管理
- 添加测试:编写单元测试和集成测试
10. 参考文档
11. 项目下载
本项目已上传至 GitHub,可直接下载使用: