【微服务组件】Springboot结合Dubbo实现RPC调用
Springboot结合Dubbo实现RPC调用
- 一、环境准备
- 1. 依赖版本
- 二、项目结构
- 三、公共接口定义(`dubbo-api` 模块)
- 四、XML 配置方式实现
- 1. 服务提供者(`dubbo-provider`)
- (1)`pom.xml` 依赖
- (2)XML 配置文件 `dubbo-provider.xml`
- (3)服务实现类
- (4)启动类(加载 XML 配置)
- 2. 服务消费者(`dubbo-consumer`)
- (1)`pom.xml` 依赖(与 Provider 一致)
- (2)XML 配置文件 `dubbo-consumer.xml`
- (3)调用远程服务的组件
- (4)启动类(加载 XML 并测试)
- 五、JavaConfig 配置方式实现
- 1. 服务提供者(`dubbo-provider`)
- (1)配置类 `DubboProviderConfig`
- (2)服务实现类(用 `@DubboService` 注解)
- (3)启动类(导入配置类)
- 2. 服务消费者(`dubbo-consumer`)
- (1)配置类 `DubboConsumerConfig`
- (2)调用远程服务的组件(用 `@DubboReference` 注解)
- (3)启动类(测试调用)
- 六、运行与验证
- 1. 启动注册中心(ZooKeeper)
- 2. 启动服务提供者
- 3. 启动服务消费者
- 七、关键说明
- 八、新增一个Provider服务完整步骤
- 一、前置准备
- 1. 项目结构(已有 Dubbo 环境)
- 二、新增数据提供接口(核心步骤)
- 1. 定义公共接口(`dubbo-api` 模块)
- 2. 服务提供者实现接口(`dubbo-provider` 模块)
- (1)实现接口(服务逻辑)
- (2)配置服务暴露(Dubbo 配置)
- 方式 1:JavaConfig 配置(推荐)
- 方式 2:XML 配置(传统方式)
- (3)启动类(加载配置)
- 3. 服务消费者引用接口(`dubbo-consumer` 模块)
- (1)引用接口(注入代理对象)
- (2)配置 Dubbo 消费者(可选,若未全局配置)
- (3)启动类(测试调用)
- 三、测试验证
- 1. 启动注册中心(ZooKeeper)
- 2. 启动服务提供者
- 3. 启动服务消费者
- 四、关键说明
- 1. 接口共享
- 2. 服务暴露与引用
- 3. 注册中心
- 4. 序列化
- 五、常见问题排查
- 九、扩展建议
- 相关文献
以下是基于 Java 8 + Spring Boot 2.7.x + Dubbo 3.1.5 的完整 RPC 实现示例,包含 XML 配置 和 JavaConfig 配置 两种方式,覆盖 公共接口、服务提供者、服务消费者全流程。
一、环境准备
1. 依赖版本
| 组件 | 版本 |
|---|---|
| Spring Boot | 2.7.18 |
| Dubbo | 3.1.5 |
| Dubbo Spring Boot Starter | 3.1.5 |
| ZooKeeper 客户端(Curator) | 5.3.0 |
| JDK | 1.8 |
二、项目结构
dubbo-demo-java8/
├── dubbo-api/ # 公共接口模块(Provider/Consumer 共享)
├── dubbo-provider/ # 服务提供者(暴露 RPC 服务)
└── dubbo-consumer/ # 服务消费者(调用远程 RPC 服务)
三、公共接口定义(dubbo-api 模块)
定义服务接口,Provider 实现、Consumer 引用此接口:
// com/example/api/UserService.java
package com.example.api;public interface UserService {/*** 根据用户ID获取用户信息* @param userId 用户ID* @return 用户信息字符串*/String getUserInfo(Long userId);
}
四、XML 配置方式实现
1. 服务提供者(dubbo-provider)
(1)pom.xml 依赖
<dependencies><!-- Spring Boot 基础 --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId><version>2.7.18</version></dependency><!-- Dubbo Spring Boot Starter --><dependency><groupId>org.apache.dubbo</groupId><artifactId>dubbo-spring-boot-starter</artifactId><version>3.1.5</version></dependency><!-- ZooKeeper 客户端(注册中心) --><dependency><groupId>org.apache.curator</groupId><artifactId>curator-recipes</artifactId><version>5.3.0</version></dependency><!-- 公共接口模块 --><dependency><groupId>com.example</groupId><artifactId>dubbo-api</artifactId><version>1.0.0</version></dependency>
</dependencies>
(2)XML 配置文件 dubbo-provider.xml
在 src/main/resources 下创建 XML 配置:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://dubbo.apache.org/schema/dubbohttp://dubbo.apache.org/schema/dubbo/dubbo.xsd"><!-- 1. 应用配置(必填) --><dubbo:application name="dubbo-provider-java8"/><!-- 2. 注册中心配置(ZooKeeper) --><dubbo:registry address="zookeeper://127.0.0.1:2181"/><!-- 3. 协议配置(Dubbo 协议 + 端口 20880) --><dubbo:protocol name="dubbo" port="20880"/><!-- 4. 服务暴露:绑定接口与实现类 --><dubbo:service interface="com.example.api.UserService" ref="userService"/><bean id="userService" class="com.example.provider.service.UserServiceImpl"/>
</beans>
(3)服务实现类
// com/example/provider/service/UserServiceImpl.java
package com.example.provider.service;import com.example.api.UserService;public class UserServiceImpl implements UserService {@Overridepublic String getUserInfo(Long userId) {return "【Provider】User-" + userId + "(XML配置·Java8)";}
}
(4)启动类(加载 XML 配置)
// DubboProviderApplication.java
package com.example.provider;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.ImportResource;@SpringBootApplication
@ImportResource(locations = "classpath:dubbo-provider.xml") // 加载 Dubbo XML 配置
public class DubboProviderApplication {public static void main(String[] args) {SpringApplication.run(DubboProviderApplication.class, args);System.out.println("Dubbo Provider(XML·Java8)已启动");}
}
2. 服务消费者(dubbo-consumer)
(1)pom.xml 依赖(与 Provider 一致)
<!-- 依赖同 dubbo-provider,仅替换 artifactId -->
<artifactId>dubbo-consumer</artifactId>
(2)XML 配置文件 dubbo-consumer.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://dubbo.apache.org/schema/dubbohttp://dubbo.apache.org/schema/dubbo/dubbo.xsd"><!-- 1. 应用配置 --><dubbo:application name="dubbo-consumer-java8"/><!-- 2. 注册中心配置(与 Provider 一致) --><dubbo:registry address="zookeeper://127.0.0.1:2181"/><!-- 3. 服务引用:生成远程服务的本地代理 --><dubbo:reference id="userService" interface="com.example.api.UserService"/>
</beans>
(3)调用远程服务的组件
// com/example/consumer/service/ConsumerService.java
package com.example.consumer.service;import com.example.api.UserService;
import org.springframework.stereotype.Service;import javax.annotation.Resource;@Service
public class ConsumerService {@Resource // 注入 Dubbo 生成的代理对象private UserService userService;public String callProvider(Long userId) {return userService.getUserInfo(userId);}
}
(4)启动类(加载 XML 并测试)
// DubboConsumerApplication.java
package com.example.consumer;import com.example.consumer.service.ConsumerService;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.ImportResource;@SpringBootApplication
@ImportResource(locations = "classpath:dubbo-consumer.xml")
public class DubboConsumerApplication {public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(DubboConsumerApplication.class, args);// 测试调用远程服务ConsumerService consumer = context.getBean(ConsumerService.class);String result = consumer.callProvider(1L);System.out.println("Consumer 调用结果(XML·Java8):" + result);context.close();}
}
五、JavaConfig 配置方式实现
1. 服务提供者(dubbo-provider)
(1)配置类 DubboProviderConfig
// DubboProviderConfig.java
package com.example.provider.config;import com.example.api.UserService;
import com.example.provider.service.UserServiceImpl;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.ServiceConfig;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
@EnableDubbo(scanBasePackages = "com.example.provider.service") // 扫描 @DubboService 注解
public class DubboProviderConfig {// 1. 应用配置@Beanpublic ApplicationConfig applicationConfig() {ApplicationConfig config = new ApplicationConfig();config.setName("dubbo-provider-java8-config");return config;}// 2. 注册中心配置@Beanpublic RegistryConfig registryConfig() {RegistryConfig config = new RegistryConfig();config.setAddress("zookeeper://127.0.0.1:2181");return config;}// 3. 协议配置@Beanpublic ProtocolConfig protocolConfig() {ProtocolConfig config = new ProtocolConfig();config.setName("dubbo");config.setPort(20881); // 与 XML 端口区分(测试用)return config;}// 4. 服务暴露(绑定接口与实现类)@Beanpublic ServiceConfig<UserService> userServiceConfig(UserService userService) {ServiceConfig<UserService> config = new ServiceConfig<>();config.setInterface(UserService.class);config.setRef(userService);config.setProtocol(protocolConfig()); // 使用上面的协议配置return config;}
}
(2)服务实现类(用 @DubboService 注解)
// com/example/provider/service/UserServiceImpl.java
package com.example.provider.service;import com.example.api.UserService;
import org.apache.dubbo.config.annotation.DubboService;@DubboService // 暴露服务(等价于 XML 的 <dubbo:service>)
public class UserServiceImpl implements UserService {@Overridepublic String getUserInfo(Long userId) {return "【Provider】User-" + userId + "(JavaConfig·Java8)";}
}
(3)启动类(导入配置类)
// DubboProviderApplication.java
package com.example.provider;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Import;@SpringBootApplication
@Import(DubboProviderConfig.class) // 导入 Dubbo 配置类
public class DubboProviderApplication {public static void main(String[] args) {SpringApplication.run(DubboProviderApplication.class, args);System.out.println("Dubbo Provider(JavaConfig·Java8)已启动");}
}
2. 服务消费者(dubbo-consumer)
(1)配置类 DubboConsumerConfig
// DubboConsumerConfig.java
package com.example.consumer.config;import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
@EnableDubbo(scanBasePackages = "com.example.consumer.service") // 扫描 @DubboReference
public class DubboConsumerConfig {// 1. 应用配置@Beanpublic ApplicationConfig applicationConfig() {ApplicationConfig config = new ApplicationConfig();config.setName("dubbo-consumer-java8-config");return config;}// 2. 注册中心配置(与 Provider 一致)@Beanpublic RegistryConfig registryConfig() {RegistryConfig config = new RegistryConfig();config.setAddress("zookeeper://127.0.0.1:2181");return config;}
}
(2)调用远程服务的组件(用 @DubboReference 注解)
// com/example/consumer/service/ConsumerService.java
package com.example.consumer.service;import com.example.api.UserService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;@Service
public class ConsumerService {@DubboReference // 引用远程服务(生成代理对象)private UserService userService;public String callProvider(Long userId) {return userService.getUserInfo(userId);}
}
(3)启动类(测试调用)
// DubboConsumerApplication.java
package com.example.consumer;import com.example.consumer.service.ConsumerService;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import;@SpringBootApplication
@Import(DubboConsumerConfig.class)
public class DubboConsumerApplication {public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(DubboConsumerApplication.class, args);// 测试调用ConsumerService consumer = context.getBean(ConsumerService.class);String result = consumer.callProvider(1L);System.out.println("Consumer 调用结果(JavaConfig·Java8):" + result);context.close();}
}
六、运行与验证
1. 启动注册中心(ZooKeeper)
下载并启动 ZooKeeper(默认端口 2181):
- 下载地址:https://zookeeper.apache.org/releases.html
- 启动命令:
bin/zkServer.sh start(Linux/Mac)或bin/zkServer.cmd(Windows)
2. 启动服务提供者
- XML 配置:运行
DubboProviderApplication(XML 版)。 - JavaConfig 配置:运行
DubboProviderApplication(JavaConfig 版)。
3. 启动服务消费者
运行 DubboConsumerApplication,控制台输出:
Consumer 调用结果(XML·Java8):【Provider】User-1(XML配置·Java8)
# 或
Consumer 调用结果(JavaConfig·Java8):【Provider】User-1(JavaConfig·Java8)
七、关键说明
- Java 8 兼容:Dubbo 3.1.5 完全支持 Java 8,无需额外配置。
- Spring Boot 2.7 集成:通过
dubbo-spring-boot-starter自动配置 Dubbo 组件,兼容 Spring Boot 2.7.x。 - 注册中心:Provider 启动时将服务注册到 ZooKeeper,Consumer 启动时订阅服务列表。
- 配置差异:
- XML 配置:通过
<dubbo:service>/<dubbo:reference>声明服务暴露/引用。 - JavaConfig:通过
@DubboService/@DubboReference注解 +@EnableDubbo实现。
- XML 配置:通过
八、新增一个Provider服务完整步骤
在 Spring Boot 2.7.x + Java 8 环境下新增一个 Dubbo 数据提供接口,需遵循 接口定义→服务实现→服务暴露→服务引用→测试验证 的流程。以下是完整详细步骤,包含代码和配置示例(基于 Dubbo 3.1.5)。
一、前置准备
1. 项目结构(已有 Dubbo 环境)
假设已有 Dubbo 基础项目,结构如下(新增接口需扩展):
dubbo-demo/
├── dubbo-api/ # 公共接口模块(新增接口放此处)
├── dubbo-provider/ # 服务提供者(实现新增接口)
└── dubbo-consumer/ # 服务消费者(引用新增接口)
二、新增数据提供接口(核心步骤)
1. 定义公共接口(dubbo-api 模块)
在公共接口模块 dubbo-api 中新增数据提供接口,例如 UserDataService(获取用户数据):
// com/example/api/UserDataService.java
package com.example.api;import java.util.List;/*** 新增:用户数据提供接口(Dubbo 服务接口)*/
public interface UserDataService {/*** 根据用户ID列表获取用户信息* @param userIds 用户ID列表* @return 用户信息列表*/List<User> getUserList(List<Long> userIds);/*** 新增用户数据* @param user 用户对象* @return 新增结果(成功/失败)*/boolean addUser(User user);
}// 用户实体类(需序列化,Dubbo 传输需要)
class User implements java.io.Serializable {private Long id;private String name;private Integer age;// 构造方法、Getter/Setter 省略(实际需补充)
}
说明:
- 接口需定义在
dubbo-api模块,Provider 和 Consumer 共享此接口。 - 实体类需实现
Serializable,避免 Dubbo 序列化失败。
2. 服务提供者实现接口(dubbo-provider 模块)
在服务提供者中实现 UserDataService 接口,并通过 Dubbo 注解暴露服务。
(1)实现接口(服务逻辑)
// com/example/provider/service/UserDataServiceImpl.java
package com.example.provider.service;import com.example.api.User;
import com.example.api.UserDataService;
import org.apache.dubbo.config.annotation.DubboService;import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;@DubboService // Dubbo 3.x 注解:暴露服务(等价于 XML 的 <dubbo:service>)
public class UserDataServiceImpl implements UserDataService {/*** 模拟数据库查询:根据用户ID列表获取用户信息*/@Overridepublic List<User> getUserList(List<Long> userIds) {// 模拟数据:从数据库查询(实际替换为真实 DAO 调用)return userIds.stream().map(id -> new User(id, "User-" + id, 20 + id % 10)).collect(Collectors.toList());}/*** 模拟数据库插入:新增用户数据*/@Overridepublic boolean addUser(User user) {// 模拟插入数据库(实际替换为真实 DAO 调用)System.out.println("新增用户成功:" + user.getName());return true; // 返回操作结果}
}
(2)配置服务暴露(Dubbo 配置)
需配置 Dubbo 的应用名、注册中心、协议,并通过 ServiceConfig 或注解暴露服务。以下提供 JavaConfig 和 XML 两种配置方式(任选其一)。
方式 1:JavaConfig 配置(推荐)
创建 DubboProviderConfig 配置类,定义 Dubbo 核心组件:
// DubboProviderConfig.java
package com.example.provider.config;import com.example.api.UserDataService;
import com.example.provider.service.UserDataServiceImpl;
import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.ProtocolConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.ServiceConfig;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
@EnableDubbo(scanBasePackages = "com.example.provider.service") // 扫描 @DubboService 注解
public class DubboProviderConfig {// 1. 应用配置(必填)@Beanpublic ApplicationConfig applicationConfig() {ApplicationConfig config = new ApplicationConfig();config.setName("dubbo-provider-userdata"); // 应用名(唯一标识)return config;}// 2. 注册中心配置(ZooKeeper)@Beanpublic RegistryConfig registryConfig() {RegistryConfig config = new RegistryConfig();config.setAddress("zookeeper://127.0.0.1:2181"); // ZooKeeper 地址return config;}// 3. 协议配置(Dubbo 协议 + 端口)@Beanpublic ProtocolConfig protocolConfig() {ProtocolConfig config = new ProtocolConfig();config.setName("dubbo"); // 协议名(默认 dubbo)config.setPort(20880); // 端口(默认 20880,可自定义)return config;}// 4. 服务暴露:绑定接口与实现类@Beanpublic ServiceConfig<UserDataService> userDataServiceConfig(UserDataService userService) {ServiceConfig<UserDataService> config = new ServiceConfig<>();config.setInterface(UserDataService.class); // 接口类config.setRef(userService); // 接口实现类(@DubboService 已注入)config.setProtocol(protocolConfig()); // 使用配置的协议return config;}
}
方式 2:XML 配置(传统方式)
在 src/main/resources 下创建 dubbo-provider.xml,声明服务暴露:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://dubbo.apache.org/schema/dubbohttp://dubbo.apache.org/schema/dubbo/dubbo.xsd"><!-- 应用配置 --><dubbo:application name="dubbo-provider-userdata"/><!-- 注册中心配置 --><dubbo:registry address="zookeeper://127.0.0.1:2181"/><!-- 协议配置 --><dubbo:protocol name="dubbo" port="20880"/><!-- 服务暴露:绑定接口与实现类 --><dubbo:service interface="com.example.api.UserDataService" ref="userDataService"/><bean id="userDataService" class="com.example.provider.service.UserDataServiceImpl"/>
</beans>
说明:
- 若用 XML 配置,服务实现类无需
@DubboService注解,通过<dubbo:service>声明暴露。
(3)启动类(加载配置)
// DubboProviderApplication.java
package com.example.provider;import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Import; // JavaConfig 需导入配置类
// 或 XML 配置:import org.springframework.context.annotation.ImportResource;@SpringBootApplication
// JavaConfig 方式:导入 Dubbo 配置类
@Import(DubboProviderConfig.class)
// XML 配置方式:加载 XML 文件(二选一)
// @ImportResource(locations = "classpath:dubbo-provider.xml")
public class DubboProviderApplication {public static void main(String[] args) {SpringApplication.run(DubboProviderApplication.class, args);System.out.println("Dubbo Provider(用户数据服务)已启动");}
}
3. 服务消费者引用接口(dubbo-consumer 模块)
在服务消费者中引用新增的 UserDataService 接口,通过 Dubbo 代理调用远程服务。
(1)引用接口(注入代理对象)
// com/example/consumer/service/UserDataConsumerService.java
package com.example.consumer.service;import com.example.api.User;
import com.example.api.UserDataService;
import org.apache.dubbo.config.annotation.DubboReference;
import org.springframework.stereotype.Service;import java.util.Arrays;
import java.util.List;@Service
public class UserDataConsumerService {/*** 引用远程服务(Dubbo 生成代理对象)*/@DubboReference // 等价于 XML 的 <dubbo:reference>private UserDataService userDataService;/*** 调用远程方法:获取用户列表*/public List<User> fetchUserList(List<Long> userIds) {return userDataService.getUserList(userIds);}/*** 调用远程方法:新增用户*/public boolean addUser(User user) {return userDataService.addUser(user);}
}
(2)配置 Dubbo 消费者(可选,若未全局配置)
若消费者未全局配置 Dubbo,需创建 DubboConsumerConfig 配置类:
// DubboConsumerConfig.java
package com.example.consumer.config;import org.apache.dubbo.config.ApplicationConfig;
import org.apache.dubbo.config.RegistryConfig;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;@Configuration
@EnableDubbo(scanBasePackages = "com.example.consumer.service") // 扫描 @DubboReference
public class DubboConsumerConfig {@Beanpublic ApplicationConfig applicationConfig() {ApplicationConfig config = new ApplicationConfig();config.setName("dubbo-consumer-userdata");return config;}@Beanpublic RegistryConfig registryConfig() {RegistryConfig config = new RegistryConfig();config.setAddress("zookeeper://127.0.0.1:2181");return config;}
}
(3)启动类(测试调用)
// DubboConsumerApplication.java
package com.example.consumer;import com.example.consumer.service.UserDataConsumerService;
import com.example.api.User;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Import; // JavaConfig 方式
// 或 XML 配置:import org.springframework.context.annotation.ImportResource;@SpringBootApplication
// JavaConfig 方式:导入 Dubbo 配置类
@Import(DubboConsumerConfig.class)
// XML 配置方式:加载 XML 文件(二选一)
// @ImportResource(locations = "classpath:dubbo-consumer.xml")
public class DubboConsumerApplication {public static void main(String[] args) {ConfigurableApplicationContext context = SpringApplication.run(DubboConsumerApplication.class, args);// 测试调用新增接口UserDataConsumerService consumer = context.getBean(UserDataConsumerService.class);// 测试获取用户列表List<Long> userIds = Arrays.asList(1L, 2L, 3L);List<User> users = consumer.fetchUserList(userIds);System.out.println("获取用户列表结果:" + users);// 测试新增用户User newUser = new User(4L, "NewUser", 25);boolean success = consumer.addUser(newUser);System.out.println("新增用户结果:" + success);context.close();}
}
三、测试验证
1. 启动注册中心(ZooKeeper)
确保 ZooKeeper 已启动(默认端口 2181):
# Linux/Mac
bin/zkServer.sh start# Windows
bin/zkServer.cmd
2. 启动服务提供者
运行 DubboProviderApplication,控制台输出:
Dubbo Provider(用户数据服务)已启动
3. 启动服务消费者
运行 DubboConsumerApplication,控制台输出:
获取用户列表结果:[User{id=1, name='User-1', age=21}, User{id=2, name='User-2', age=22}, User{id=3, name='User-3', age=23}]
新增用户成功:NewUser
新增用户结果:true
四、关键说明
1. 接口共享
dubbo-api 模块的接口需被 Provider 和 Consumer 依赖,确保接口定义一致。
2. 服务暴露与引用
- Provider:通过
@DubboService(注解)或<dubbo:service>(XML)暴露服务。 - Consumer:通过
@DubboReference(注解)或<dubbo:reference>(XML)注入代理对象。
3. 注册中心
Provider 启动时将服务注册到 ZooKeeper,Consumer 启动时订阅注册中心的服务列表,实现动态发现。
4. 序列化
Dubbo 默认使用 Hessian2 序列化,实体类需实现 Serializable,避免序列化失败。
五、常见问题排查
- 接口找不到:检查
dubbo-api模块是否被 Provider 和 Consumer 正确依赖。 - 服务未注册:检查 Provider 的注册中心地址是否正确,ZooKeeper 是否启动。
- 调用失败:检查 Consumer 的
@DubboReference是否正确注入,接口名是否匹配。
九、扩展建议
- 多注册中心:可配置多个注册中心(如 ZooKeeper + Nacos),提高可用性。
- 负载均衡:通过
@DubboReference(loadbalance = "roundrobin")配置负载均衡策略。 - 超时与重试:通过
@DubboReference(timeout = 3000, retries = 2)配置调用超时和重试次数。
相关文献
【微服务组件】Dubbo底层原理以及核心代码解读
【微服务知识】开源RPC框架Dubbo入门介绍
Dubbo框架微服务开发
Dubbo3.x速览
