整合流程
1.启动zookeeper注册中心
这里我是在自己的云服务器上使用docker部署的,运行docker run -d -p 2181:2181 zookeeper
即可。
2.构建项目
项目结构如下图,api模块用于暴露公共的Service接口,provider模块为服务提供者,consumer模块为服务调用者。

3.代码编写
3.1.api模块
api模块只需定义一个UserService接口即可,结构如下图:

UserService.java代码如下:
1 2 3 4 5
| package com.penciy.service;
public interface UserService { String hello(String name); }
|
pom.xml如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion>
<groupId>com.penciy</groupId> <artifactId>api</artifactId> <version>1.0-SNAPSHOT</version>
<properties> <maven.compiler.source>17</maven.compiler.source> <maven.compiler.target>17</maven.compiler.target> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties>
</project>
|
3.2.服务提供者provider
服务提供者负责实现 api模块中定义的服务接口,并将这些服务注册到 ZooKeeper 注册中心。整体结构如下图:

pom.xml如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90
| <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.penciy</groupId> <artifactId>provider</artifactId> <version>0.0.1-SNAPSHOT</version> <name>provider</name> <description>provider</description> <properties> <java.version>17</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot.version>2.6.13</spring-boot.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
<dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>3.3.0</version> </dependency>
<dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-zookeeper-curator5-spring-boot-starter</artifactId> <version>3.3.0</version> </dependency>
<dependency> <groupId>com.penciy</groupId> <artifactId>api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>17</source> <target>17</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${spring-boot.version}</version> <configuration> <mainClass>com.penciy.provider.ProviderApplication</mainClass> <skip>true</skip> </configuration> <executions> <execution> <id>repackage</id> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build>
</project>
|
UserServiceImpl.java代码如下,使用 Dubbo 注解 @DubboService
将实现的服务注册到 ZooKeeper 注册中心,以便服务消费者可以发现和调用这些服务。:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| package com.penciy.provider.service;
import com.penciy.service.UserService; import org.apache.dubbo.config.annotation.DubboService; import org.springframework.stereotype.Component;
@DubboService @Component public class UserServiceImpl implements UserService {
@Override public String hello(String name) { return "hello dubbo, I am " + name; } }
|
启动类ProviderApplication.java代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| package com.penciy.provider;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
@EnableDubbo @SpringBootApplication public class ProviderApplication {
public static void main(String[] args) { SpringApplication.run(ProviderApplication.class, args); }
}
|
application.properties如下(这里隐去了我的服务器ip):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| server.port=8081
dubbo.registry.address=zookeeper://xx.xxx.xxx.xxx:2181
dubbo.registry.register-mode=instance
dubbo.application.name=demo-provider
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
dubbo.scan.base-packages=com.penciy.provider.service
|
3.3.服务消费者consumer
consumer模块是服务的消费者,它依赖api模块中的服务接口,从 ZooKeeper 注册中心获取服务提供者的信息,并调用这些服务。整体结构如下:

pom.xml如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89
| <?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.penciy</groupId> <artifactId>consumer</artifactId> <version>0.0.1-SNAPSHOT</version> <name>consumer</name> <description>consumer</description> <properties> <java.version>17</java.version> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <spring-boot.version>2.6.13</spring-boot.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency>
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency>
<dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>3.3.0</version> </dependency>
<dependency> <groupId>org.apache.dubbo</groupId> <artifactId>dubbo-zookeeper-curator5-spring-boot-starter</artifactId> <version>3.3.0</version> </dependency>
<dependency> <groupId>com.penciy</groupId> <artifactId>api</artifactId> <version>1.0-SNAPSHOT</version> </dependency> </dependencies> <dependencyManagement> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-dependencies</artifactId> <version>${spring-boot.version}</version> <type>pom</type> <scope>import</scope> </dependency> </dependencies> </dependencyManagement>
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.1</version> <configuration> <source>17</source> <target>17</target> <encoding>UTF-8</encoding> </configuration> </plugin> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <version>${spring-boot.version}</version> <configuration> <mainClass>com.penciy.consumer.ConsumerApplication</mainClass> <skip>true</skip> </configuration> <executions> <execution> <id>repackage</id> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> </plugins> </build> </project>
|
HelloController.java代码如下,这里的userService是通过@DubboReference注解进行注入的,实际运行时会使用一个动态代理调用注册中心中的远程服务:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| package com.penciy.consumer.controller;
import com.penciy.service.UserService; import org.apache.dubbo.config.annotation.DubboReference; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController;
@RestController @RequestMapping("/hello") public class HelloController {
@DubboReference UserService userService;
@GetMapping("/dubbo") public String hello(String name) { return userService.hello(name); } }
|
启动类ConsumerApplication如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| package com.penciy.consumer;
import org.apache.dubbo.config.spring.context.annotation.EnableDubbo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication;
@EnableDubbo @SpringBootApplication public class ConsumerApplication {
public static void main(String[] args) { SpringApplication.run(ConsumerApplication.class, args); }
}
|
application.properties如下:
1 2 3 4 5 6 7 8 9 10 11
| server.port=8082
dubbo.registry.address=zookeeper://xx.xxx.xxx.xxx:2181
dubbo.registry.register-mode=instance
dubbo.application.name=demo-consumer
dubbo.protocol.name=dubbo
dubbo.application.qos-port=33333
|
4.功能测试
分别启动provider和consumer,访问localhost:8082/hello/dubbo/?name=penciy,发现服务消费者可以成功调用提供者的接口实现类:

5.总结
dubbo的入门使用十分简单,只需要引入依赖并配置,然后在服务调用者和服务提供者的启动类上加入@EnableDubbo
注解,在服务提供者提供的远程服务实现上加入@DubboService
,在服务调用者需要注入的远程服务上加入@DubboReference
注解即可。
6.踩坑记录
**问题:**服务消费者始终无法发现注册中心的服务
使用 Zookeeper 作为注册中心实现自动服务发现 | Apache Dubbo中有一句话:
- Dubbo 3.3.0 版本开始正式支持 JDK 17,如果您使用 JDK 17,则必须选用 dubbo-dependencies-zookeeper-curator5 或 dubbo-zookeeper-curator5-spring-boot-starter 依赖,对应的 Zookeeper Server 推荐是 3.8.0 版本及以上。
一开始使用的是3.5.x的zookeeper,猜测可能是版本原因,用docker重新安装了高版本的zookeeper后问题解决。
__END__