【微服务组件】Springboot结合Dubbo实现RPC调用

Springboot结合Dubbo实现RPC调用

    • 一、环境准备
      • [1. 依赖版本](#1. 依赖版本)
    • 二、项目结构
    • [三、公共接口定义(`dubbo-api` 模块)](#三、公共接口定义(dubbo-api 模块))
    • [四、XML 配置方式实现](#四、XML 配置方式实现)
      • [1. 服务提供者(`dubbo-provider`)](#1. 服务提供者(dubbo-provider))
        • [(1)`pom.xml` 依赖](#(1)pom.xml 依赖)
        • [(2)XML 配置文件 `dubbo-provider.xml`](#(2)XML 配置文件 dubbo-provider.xml)
        • (3)服务实现类
        • [(4)启动类(加载 XML 配置)](#(4)启动类(加载 XML 配置))
      • [2. 服务消费者(`dubbo-consumer`)](#2. 服务消费者(dubbo-consumer))
        • [(1)`pom.xml` 依赖(与 Provider 一致)](#(1)pom.xml 依赖(与 Provider 一致))
        • [(2)XML 配置文件 `dubbo-consumer.xml`](#(2)XML 配置文件 dubbo-consumer.xml)
        • (3)调用远程服务的组件
        • [(4)启动类(加载 XML 并测试)](#(4)启动类(加载 XML 并测试))
    • [五、JavaConfig 配置方式实现](#五、JavaConfig 配置方式实现)
      • [1. 服务提供者(`dubbo-provider`)](#1. 服务提供者(dubbo-provider))
        • [(1)配置类 `DubboProviderConfig`](#(1)配置类 DubboProviderConfig)
        • [(2)服务实现类(用 `@DubboService` 注解)](#(2)服务实现类(用 @DubboService 注解))
        • (3)启动类(导入配置类)
      • [2. 服务消费者(`dubbo-consumer`)](#2. 服务消费者(dubbo-consumer))
        • [(1)配置类 `DubboConsumerConfig`](#(1)配置类 DubboConsumerConfig)
        • [(2)调用远程服务的组件(用 `@DubboReference` 注解)](#(2)调用远程服务的组件(用 @DubboReference 注解))
        • (3)启动类(测试调用)
    • 六、运行与验证
      • [1. 启动注册中心(ZooKeeper)](#1. 启动注册中心(ZooKeeper))
      • [2. 启动服务提供者](#2. 启动服务提供者)
      • [3. 启动服务消费者](#3. 启动服务消费者)
    • 七、关键说明
    • 八、新增一个Provider服务完整步骤
      • 一、前置准备
        • [1. 项目结构(已有 Dubbo 环境)](#1. 项目结构(已有 Dubbo 环境))
      • 二、新增数据提供接口(核心步骤)
        • [1. 定义公共接口(`dubbo-api` 模块)](#1. 定义公共接口(dubbo-api 模块))
        • [2. 服务提供者实现接口(`dubbo-provider` 模块)](#2. 服务提供者实现接口(dubbo-provider 模块))
        • [3. 服务消费者引用接口(`dubbo-consumer` 模块)](#3. 服务消费者引用接口(dubbo-consumer 模块))
      • 三、测试验证
        • [1. 启动注册中心(ZooKeeper)](#1. 启动注册中心(ZooKeeper))
        • [2. 启动服务提供者](#2. 启动服务提供者)
        • [3. 启动服务消费者](#3. 启动服务消费者)
      • 四、关键说明
        • [1. 接口共享](#1. 接口共享)
        • [2. 服务暴露与引用](#2. 服务暴露与引用)
        • [3. 注册中心](#3. 注册中心)
        • [4. 序列化](#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 引用此接口:

java 复制代码
// 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 依赖
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 复制代码
<?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/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://dubbo.apache.org/schema/dubbo
       http://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)服务实现类
java 复制代码
// com/example/provider/service/UserServiceImpl.java
package com.example.provider.service;

import com.example.api.UserService;

public class UserServiceImpl implements UserService {
    @Override
    public String getUserInfo(Long userId) {
        return "【Provider】User-" + userId + "(XML配置·Java8)";
    }
}
(4)启动类(加载 XML 配置)
java 复制代码
// 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 一致)
xml 复制代码
<!-- 依赖同 dubbo-provider,仅替换 artifactId -->
<artifactId>dubbo-consumer</artifactId>
(2)XML 配置文件 dubbo-consumer.xml
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/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://dubbo.apache.org/schema/dubbo
       http://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)调用远程服务的组件
java 复制代码
// 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 并测试)
java 复制代码
// 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
java 复制代码
// 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. 应用配置
    @Bean
    public ApplicationConfig applicationConfig() {
        ApplicationConfig config = new ApplicationConfig();
        config.setName("dubbo-provider-java8-config");
        return config;
    }

    // 2. 注册中心配置
    @Bean
    public RegistryConfig registryConfig() {
        RegistryConfig config = new RegistryConfig();
        config.setAddress("zookeeper://127.0.0.1:2181");
        return config;
    }

    // 3. 协议配置
    @Bean
    public ProtocolConfig protocolConfig() {
        ProtocolConfig config = new ProtocolConfig();
        config.setName("dubbo");
        config.setPort(20881); // 与 XML 端口区分(测试用)
        return config;
    }

    // 4. 服务暴露(绑定接口与实现类)
    @Bean
    public ServiceConfig<UserService> userServiceConfig(UserService userService) {
        ServiceConfig<UserService> config = new ServiceConfig<>();
        config.setInterface(UserService.class);
        config.setRef(userService);
        config.setProtocol(protocolConfig()); // 使用上面的协议配置
        return config;
    }
}
(2)服务实现类(用 @DubboService 注解)
java 复制代码
// 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 {
    @Override
    public String getUserInfo(Long userId) {
        return "【Provider】User-" + userId + "(JavaConfig·Java8)";
    }
}
(3)启动类(导入配置类)
java 复制代码
// 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
java 复制代码
// 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. 应用配置
    @Bean
    public ApplicationConfig applicationConfig() {
        ApplicationConfig config = new ApplicationConfig();
        config.setName("dubbo-consumer-java8-config");
        return config;
    }

    // 2. 注册中心配置(与 Provider 一致)
    @Bean
    public RegistryConfig registryConfig() {
        RegistryConfig config = new RegistryConfig();
        config.setAddress("zookeeper://127.0.0.1:2181");
        return config;
    }
}
(2)调用远程服务的组件(用 @DubboReference 注解)
java 复制代码
// 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)启动类(测试调用)
java 复制代码
// 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):

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)

七、关键说明

  1. Java 8 兼容:Dubbo 3.1.5 完全支持 Java 8,无需额外配置。
  2. Spring Boot 2.7 集成 :通过 dubbo-spring-boot-starter 自动配置 Dubbo 组件,兼容 Spring Boot 2.7.x。
  3. 注册中心:Provider 启动时将服务注册到 ZooKeeper,Consumer 启动时订阅服务列表。
  4. 配置差异 :
    • XML 配置:通过 <dubbo:service>/<dubbo:reference> 声明服务暴露/引用。
    • JavaConfig:通过 @DubboService/@DubboReference 注解 + @EnableDubbo 实现。

八、新增一个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(获取用户数据):

java 复制代码
// 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)实现接口(服务逻辑)
java 复制代码
// 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列表获取用户信息
     */
    @Override
    public List<User> getUserList(List<Long> userIds) {
        // 模拟数据:从数据库查询(实际替换为真实 DAO 调用)
        return userIds.stream()
                .map(id -> new User(id, "User-" + id, 20 + id % 10))
                .collect(Collectors.toList());
    }

    /**
     * 模拟数据库插入:新增用户数据
     */
    @Override
    public boolean addUser(User user) {
        // 模拟插入数据库(实际替换为真实 DAO 调用)
        System.out.println("新增用户成功:" + user.getName());
        return true; // 返回操作结果
    }
}
(2)配置服务暴露(Dubbo 配置)

需配置 Dubbo 的应用名、注册中心、协议 ,并通过 ServiceConfig 或注解暴露服务。以下提供 JavaConfig 和 XML 两种配置方式(任选其一)。

方式 1:JavaConfig 配置(推荐)

创建 DubboProviderConfig 配置类,定义 Dubbo 核心组件:

java 复制代码
// 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. 应用配置(必填)
    @Bean
    public ApplicationConfig applicationConfig() {
        ApplicationConfig config = new ApplicationConfig();
        config.setName("dubbo-provider-userdata"); // 应用名(唯一标识)
        return config;
    }

    // 2. 注册中心配置(ZooKeeper)
    @Bean
    public RegistryConfig registryConfig() {
        RegistryConfig config = new RegistryConfig();
        config.setAddress("zookeeper://127.0.0.1:2181"); // ZooKeeper 地址
        return config;
    }

    // 3. 协议配置(Dubbo 协议 + 端口)
    @Bean
    public ProtocolConfig protocolConfig() {
        ProtocolConfig config = new ProtocolConfig();
        config.setName("dubbo"); // 协议名(默认 dubbo)
        config.setPort(20880); // 端口(默认 20880,可自定义)
        return config;
    }

    // 4. 服务暴露:绑定接口与实现类
    @Bean
    public 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 复制代码
<?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/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://dubbo.apache.org/schema/dubbo
       http://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)启动类(加载配置)
java 复制代码
// 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)引用接口(注入代理对象)
java 复制代码
// 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 配置类:

java 复制代码
// 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 {

    @Bean
    public ApplicationConfig applicationConfig() {
        ApplicationConfig config = new ApplicationConfig();
        config.setName("dubbo-consumer-userdata");
        return config;
    }

    @Bean
    public RegistryConfig registryConfig() {
        RegistryConfig config = new RegistryConfig();
        config.setAddress("zookeeper://127.0.0.1:2181");
        return config;
    }
}
(3)启动类(测试调用)
java 复制代码
// 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):

bash 复制代码
# 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,避免序列化失败。

五、常见问题排查

  1. 接口找不到 :检查 dubbo-api 模块是否被 Provider 和 Consumer 正确依赖。
  2. 服务未注册:检查 Provider 的注册中心地址是否正确,ZooKeeper 是否启动。
  3. 调用失败 :检查 Consumer 的 @DubboReference 是否正确注入,接口名是否匹配。

九、扩展建议

  • 多注册中心:可配置多个注册中心(如 ZooKeeper + Nacos),提高可用性。
  • 负载均衡 :通过 @DubboReference(loadbalance = "roundrobin") 配置负载均衡策略。
  • 超时与重试 :通过 @DubboReference(timeout = 3000, retries = 2) 配置调用超时和重试次数。

相关文献

【微服务组件】Dubbo底层原理以及核心代码解读
【微服务知识】开源RPC框架Dubbo入门介绍
Dubbo框架微服务开发
Dubbo3.x速览

相关推荐
苏supper1 小时前
Spring Boot多环境配置与打包运行
spring boot·后端·spring
天衍四九-2 小时前
【无标题】
前端·spring boot·mysql·nginx·docker
今年下半年3 小时前
【Spring Boot】多种存储文件(FastDFS / MinIO / 阿里云 OSS)接入设计说明(附源码)
spring boot·分布式·中间件·简单工厂模式·策略模式
Thomas.Sir6 小时前
第11课:Nacos 多环境、多服务配置隔离 & 配置优先级详解
spring cloud·微服务·nacos
光依旧8 小时前
MCP实战手记(八):从“能跑“到“能上线“——无状态MCP Server的生产落地清单
java·人工智能·spring boot·架构·ai agent·mcp
喵了几个咪8 小时前
RushWind Admin — 契约驱动:203 条路由零手写的工程化拆解
微服务·rust·开源·admin
MZ_ZXD0018 小时前
【关注可白嫖源码】--课程设计--毕业设计-- 29210 Vue.js 3+Springboot中药材基本信息与图片查询系统
javascript·spring boot·课程设计·毕设·大作业·程序开发·毕设代做
Cheney Pan9 小时前
第4篇 Spring Boot 应用监控:Micrometer 与 JVM 指标
jvm·spring boot·后端·prometheus
小蒜学长10 小时前
基于Spring Boot+Vue的“禾源”农产品销售系统设计与实现(代码+数据库+LW)
java·spring boot·后端·农产品销售系统·产品溯源