SpringBoot+Dubbo+Zookeeper實現分布式系統
- 一、分布式系統通俗解釋
- 二、環境準備(詳細版)
- 1. 軟件版本
- 2. 安裝Zookeeper(單機模式)
- 三、完整項目結構(帶詳細注釋)
- 四、手把手代碼實現
- 步驟1:創建父工程(管理依賴)
- 步驟2:API模塊(定義服務契約)
- 步驟3:服務提供者(實現具體邏輯)
- 步驟4:服務消費者(調用遠程服務)
- 步驟5:啟動類配置
- 五、運行流程詳解
- 1. 啟動順序
- 2. 驗證步驟
- 3. 查看服務注冊情況
- 六、核心機制詳解
- 1. 服務注冊過程
- 2. 服務發現過程
- 3. 通信協議
- 七、常見問題解決方案
- 1. 服務無法注冊
- 2. 調用超時
- 3. 接口包路徑不一致
- 八、擴展實踐建議
一、分布式系統通俗解釋
場景比喻:想象一個大型超市(分布式系統):
- 收銀臺(服務消費者):處理顧客請求
- 倉庫(服務提供者):提供商品
- 總控室(Zookeeper):記錄哪個倉庫有什么商品
- 物流系統(Dubbo):負責收銀臺和倉庫之間的通信
當顧客要買可樂時:
- 收銀臺詢問總控室:哪里能拿到可樂?
- 總控室返回倉庫A的地址
- 收銀臺通過物流系統向倉庫A請求可樂
- 倉庫A將可樂送到收銀臺
二、環境準備(詳細版)
1. 軟件版本
- JDK 8
- Maven 3.6.3
- Zookeeper 3.7.0 (下載地址)
2. 安裝Zookeeper(單機模式)
# 解壓后進入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:創建父工程(管理依賴)
<!-- 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模塊(定義服務契約)
// api/src/main/java/com/example/api/CalculatorService.java
public interface CalculatorService {/*** 加法服務* @param a 加數* @param b 被加數* @return 和*/int add(int a, int b);
}
步驟3:服務提供者(實現具體邏輯)
// provider/src/main/java/com/example/provider/CalculatorServiceImpl.java
@DubboService // 關鍵注解:聲明這是Dubbo服務
public class CalculatorServiceImpl implements CalculatorService {@Overridepublic 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:服務消費者(調用遠程服務)
// 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=8080dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.consumer.timeout=3000
步驟5:啟動類配置
// 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. 啟動順序
2. 驗證步驟
- 啟動Zookeeper
- 啟動Provider(控制臺看到
Provider啟動成功!
) - 啟動Consumer
- 訪問測試接口:
應返回:http://localhost:8080/add?a=5&b=3
5 + 3 = 8
3. 查看服務注冊情況
使用Zookeeper客戶端工具(推薦PrettyZoo)連接localhost:2181,查看節點:
/dubbo/com.example.api.CalculatorService/providers
六、核心機制詳解
1. 服務注冊過程
- Provider啟動時向Zookeeper注冊自己的地址
- 注冊信息包括:IP、端口、接口名稱、版本等
- Zookeeper以臨時節點存儲這些信息
2. 服務發現過程
- Consumer啟動時訂閱所需服務
- Zookeeper推送Provider地址列表
- Dubbo根據負載均衡策略選擇Provider
3. 通信協議
- 默認使用Dubbo協議(TCP長連接)
- 數據序列化:Hessian2二進制格式
七、常見問題解決方案
1. 服務無法注冊
- 檢查Zookeeper是否運行:
telnet 127.0.0.1 2181
- 查看Provider日志是否有注冊異常
- 確認Dubbo版本與Zookeeper版本兼容
2. 調用超時
# 在consumer的配置中添加
dubbo.consumer.timeout=5000 # 單位毫秒
3. 接口包路徑不一致
必須保證接口的 全限定名 在Provider和Consumer中完全一致!
八、擴展實踐建議
- 多Provider測試:啟動兩個Provider實例,觀察負載均衡
- 服務治理:集成Dubbo Admin控制臺
- 容錯機制:添加
@DubboReference(cluster = "failover")