在两个 Java 项目中使用 Dubbo 进行通信,通常需要一个服务提供者(Provider)和一个服务消费者(Consumer),通过 Dubbo 的 RPC 机制实现服务调用。下面我将以一个简单的例子说明如何实现这一过程,假设两个项目分别是 dubbo-provider
和 dubbo-consumer
,并使用 ZooKeeper 作为注册中心。
前提条件
- 环境准备:
- JDK 1.8 或以上
- Maven(用于依赖管理)
- ZooKeeper(作为注册中心,推荐版本 3.4.x 或以上)
- 依赖:
使用 Spring Boot 和 Dubbo 的集成,依赖 Dubbo 和 ZooKeeper 客户端。
步骤 1:定义公共接口
在两个项目中共享一个接口模块(或单独的 Maven 模块),用于定义服务接口。这里假设创建一个名为 dubbo-api
的模块。
dubbo-api
项目
// 文件:com.example.api.HelloService.java
package com.example.api;
public interface HelloService {
String sayHello(String name);
}
构建并安装到本地 Maven 仓库:
mvn clean install
步骤 2:服务提供者(dubbo-provider)
服务提供者实现接口并对外暴露服务。
1. 添加依赖
在 pom.xml
中添加 Dubbo 和 Spring Boot 的依赖:
<dependencies>
<!-- Spring Boot -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.7.5</version>
</dependency>
<!-- Dubbo -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>3.0.7</version>
</dependency>
<!-- ZooKeeper 客户端 -->
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper</artifactId>
<version>3.0.7</version>
<type>pom</type>
</dependency>
<!-- 公共接口 -->
<dependency>
<groupId>com.example</groupId>
<artifactId>dubbo-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
2. 实现服务
// 文件:com.example.provider.service.HelloServiceImpl.java
package com.example.provider.service;
import com.example.api.HelloService;
import org.apache.dubbo.config.annotation.DubboService;
@DubboService(version = "1.0.0") // 暴露服务
public class HelloServiceImpl implements HelloService {
@Override
public String sayHello(String name) {
return "Hello, " + name + " from Dubbo Provider!";
}
}
3. 配置 Dubbo
在 application.yml
中配置 Dubbo 和 ZooKeeper:
spring:
application:
name: dubbo-provider
dubbo:
application:
name: dubbo-provider
registry:
address: zookeeper://127.0.0.1:2181 # ZooKeeper 地址
protocol:
name: dubbo
port: 20880 # 服务端口
scan:
base-packages: com.example.provider.service # 扫描服务实现类
4. 启动类
// 文件:com.example.provider.ProviderApplication.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);
}
}
步骤 3:服务消费者(dubbo-consumer)
服务消费者调用提供者的服务。
1. 添加依赖
在 pom.xml
中添加依赖(与提供者类似):
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.7.5</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>3.0.7</version>
</dependency>
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-dependencies-zookeeper</artifactId>
<version>3.0.7</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>com.example</groupId>
<artifactId>dubbo-api</artifactId>
<version>1.0-SNAPSHOT</version>
</dependency>
</dependencies>
2. 调用服务
使用 @DubboReference
注解引用远程服务:
// 文件:com.example.consumer.controller.HelloController.java
package com.example.consumer.controller;
import com.example.api.HelloService;
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 HelloController {
@DubboReference(version = "1.0.0") // 引用远程服务
private HelloService helloService;
@GetMapping("/hello")
public String sayHello(@RequestParam String name) {
return helloService.sayHello(name); // 调用远程服务
}
}
3. 配置 Dubbo
在 application.yml
中配置:
spring:
application:
name: dubbo-consumer
dubbo:
application:
name: dubbo-consumer
registry:
address: zookeeper://127.0.0.1:2181 # ZooKeeper 地址
4. 启动类
// 文件:com.example.consumer.ConsumerApplication.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);
}
}
步骤 4:运行与测试
启动 ZooKeeper
下载 ZooKeeper 并启动(默认端口 2181):bin/zkServer.sh start # Linux/Mac bin\zkServer.cmd start # Windows
启动服务提供者
运行ProviderApplication
,服务会注册到 ZooKeeper。启动服务消费者
运行ConsumerApplication
,消费者会从 ZooKeeper 发现服务。测试调用
打开浏览器或使用工具(如 Postman)访问:http://localhost:8080/hello?name=Alice
预期输出:
Hello, Alice from Dubbo Provider!
代码说明
- 服务提供者:
- 使用
@DubboService
暴露服务,通过version
指定版本号。 - 配置中指定了协议(
dubbo
)、端口(20880
)和注册中心(ZooKeeper)。
- 使用
- 服务消费者:
- 使用
@DubboReference
注入远程服务,与提供者的版本号一致。 - 通过注册中心自动发现服务并发起调用。
- 使用
- ZooKeeper:
- 作为注册中心,存储服务元数据,提供者和消费者通过它实现动态连接。
扩展与注意事项
- 负载均衡:Dubbo 默认支持多种负载均衡策略,可通过
@DubboReference(loadbalance = "roundrobin")
指定。 - 容错:可在消费者端配置
retries
和timeout
,如@DubboReference(retries = 2, timeout = 1000)
。 - 多协议:若需使用 gRPC 或 HTTP,可在配置中调整
protocol
。 - 依赖版本:确保 Dubbo 和 ZooKeeper 客户端版本兼容。
通过上述步骤,两个 Java 项目即可使用 Dubbo 实现高效通信。这种方式非常适合微服务架构中的服务间调用。