SpringBoot+Dubbo+Zookeeper实现分布式系统步骤

SpringBoot+Dubbo+Zookeeper实现分布式系统


一、分布式系统通俗解释

场景比喻:想象一个大型超市(分布式系统):

  • 收银台(服务消费者):处理顾客请求
  • 仓库(服务提供者):提供商品
  • 总控室(Zookeeper):记录哪个仓库有什么商品
  • 物流系统(Dubbo):负责收银台和仓库之间的通信

当顾客要买可乐时:

  1. 收银台询问总控室:哪里能拿到可乐?
  2. 总控室返回仓库A的地址
  3. 收银台通过物流系统向仓库A请求可乐
  4. 仓库A将可乐送到收银台

二、环境准备(详细版)

1. 软件版本

2. 安装Zookeeper(单机模式)

bash 复制代码
# 解压后进入conf目录
cp zoo_sample.cfg zoo.cfg
# 修改配置(关键部分)
dataDir=/tmp/zookeeper
clientPort=2181

# 启动服务(Linux/Mac)
bin/zkServer.sh start
# Windows双击zkServer.cmd

三、完整项目结构(带详细注释)

复制代码
distributed-demo
├── api           # 服务接口定义
├── provider      # 服务提供者
└── consumer      # 服务消费者

四、手把手代码实现

步骤1:创建父工程(管理依赖)

xml 复制代码
<!-- pom.xml -->
<project>
    <groupId>com.example</groupId>
    <artifactId>distributed-demo</artifactId>
    <version>1.0</version>
    <packaging>pom</packaging>
    
    <modules>
        <module>api</module>
        <module>provider</module>
        <module>consumer</module>
    </modules>

    <properties>
        <dubbo.version>2.7.15</dubbo.version>
        <zk.version>3.7.0</zk.version>
    </properties>

    <dependencies>
        <!-- Dubbo核心 -->
        <dependency>
            <groupId>org.apache.dubbo</groupId>
            <artifactId>dubbo-spring-boot-starter</artifactId>
            <version>${dubbo.version}</version>
        </dependency>
        
        <!-- Zookeeper客户端 -->
        <dependency>
            <groupId>org.apache.curator</groupId>
            <artifactId>curator-framework</artifactId>
            <version>5.1.0</version>
        </dependency>
    </dependencies>
</project>

步骤2:API模块(定义服务契约)

java 复制代码
// api/src/main/java/com/example/api/CalculatorService.java
public interface CalculatorService {
    /**
     * 加法服务
     * @param a 加数
     * @param b 被加数
     * @return 和
     */
    int add(int a, int b);
}

步骤3:服务提供者(实现具体逻辑)

java 复制代码
// provider/src/main/java/com/example/provider/CalculatorServiceImpl.java
@DubboService // 关键注解:声明这是Dubbo服务
public class CalculatorServiceImpl implements CalculatorService {
    @Override
    public int add(int a, int b) {
        System.out.println("收到请求:" + a + "+" + b);
        return a + b;
    }
}

// provider/src/main/resources/application.properties
# 应用配置
spring.application.name=calculator-provider
server.port=8081

# Dubbo配置
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
dubbo.scan.base-packages=com.example.provider

步骤4:服务消费者(调用远程服务)

java 复制代码
// consumer/src/main/java/com/example/consumer/CalculatorController.java
@RestController
public class CalculatorController {
    @DubboReference // 关键注解:引用远程服务
    private CalculatorService calculatorService;

    @GetMapping("/add")
    public String add(@RequestParam int a, @RequestParam int b) {
        return a + " + " + b + " = " + calculatorService.add(a, b);
    }
}

// consumer/src/main/resources/application.properties
spring.application.name=calculator-consumer
server.port=8080

dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.consumer.timeout=3000

步骤5:启动类配置

java 复制代码
// Provider启动类
@SpringBootApplication
@EnableDubbo // 启用Dubbo功能
public class ProviderApplication {
    public static void main(String[] args) {
        SpringApplication.run(ProviderApplication.class, args);
        System.out.println("Provider启动成功!");
    }
}

// Consumer启动类
@SpringBootApplication
@EnableDubbo
public class ConsumerApplication {
    public static void main(String[] args) {
        SpringApplication.run(ConsumerApplication.class, args);
        System.out.println("Consumer启动成功!");
    }
}

五、运行流程详解

1. 启动顺序

Zookeeper Provider Consumer 2181端口监听 注册服务信息 查询服务地址 返回Provider地址 发起RPC调用 返回计算结果 Zookeeper Provider Consumer

2. 验证步骤

  1. 启动Zookeeper

  2. 启动Provider(控制台看到Provider启动成功!)

  3. 启动Consumer

  4. 访问测试接口:

    复制代码
    http://localhost:8080/add?a=5&b=3

    应返回:5 + 3 = 8

3. 查看服务注册情况

使用Zookeeper客户端工具(推荐PrettyZoo)连接localhost:2181,查看节点:

复制代码
/dubbo/com.example.api.CalculatorService/providers

六、核心机制详解

1. 服务注册过程

  1. Provider启动时向Zookeeper注册自己的地址
  2. 注册信息包括:IP、端口、接口名称、版本等
  3. Zookeeper以临时节点存储这些信息

2. 服务发现过程

  1. Consumer启动时订阅所需服务
  2. Zookeeper推送Provider地址列表
  3. Dubbo根据负载均衡策略选择Provider

3. 通信协议

  • 默认使用Dubbo协议(TCP长连接)
  • 数据序列化:Hessian2二进制格式

七、常见问题解决方案

1. 服务无法注册

  • 检查Zookeeper是否运行:telnet 127.0.0.1 2181
  • 查看Provider日志是否有注册异常
  • 确认Dubbo版本与Zookeeper版本兼容

2. 调用超时

properties 复制代码
# 在consumer的配置中添加
dubbo.consumer.timeout=5000 # 单位毫秒

3. 接口包路径不一致

必须保证接口的 全限定名 在Provider和Consumer中完全一致!


八、扩展实践建议

  1. 多Provider测试:启动两个Provider实例,观察负载均衡
  2. 服务治理:集成Dubbo Admin控制台
  3. 容错机制 :添加@DubboReference(cluster = "failover")
相关推荐
宸津-代码粉碎机3 小时前
OpenAI 连夜迎战 Grok Bot 和 Muse:AI 智能体从 “会聊天” 到 “能办事”,现在入场还来得及吗
java·大数据·人工智能·分布式·python
程序猿乐锅4 小时前
【黑马点评 | 第八篇】Redisson分布式锁
java·数据库·spring boot·redis·分布式·spring·缓存
灯澜忆梦6 小时前
【RabbitMQ #7】 | 消息转换器
分布式·rabbitmq·ruby
需要8266 小时前
分布式事务:Seata AT/TCC/SAGA 的取舍与踩坑
java·spring boot·分布式·spring·spring cloud
CS创新实验室9 小时前
为什么三台机器就能选出一个“带头大哥“?——Raft 一致性算法,一次讲透
分布式·操作系统
正在走向自律10 小时前
从只写接口到独立交付前后端,飞算JavaAI能给Java后端工程师多少溢价?
java·springboot·ai编程·全栈开发·java求职·飞算javaai·金九银十
本人手速666+11 小时前
企微开发API如何设计客户冻结状态?WeComApi 在删除、投诉和异常客户场景中的自动化边界
运维·分布式·自动化·企业微信·企微外部群开发·wecomapi·企业微信二次开发
灯澜忆梦12 小时前
【RabbitMQ #4】 | Work 任务模型
分布式·rabbitmq
程序猿乐锅12 小时前
【黑马点评 | 第七篇】Redis 分布式锁的两种实现
java·数据库·redis·分布式·spring·缓存
千里码aicood14 小时前
基于Hadoop的机票价格波动分析系统的设计与实现
大数据·hadoop·分布式