SpringBoot使用Zookeeper實現(xiàn)分布式鎖的實現(xiàn)示例
概述
Zookeeper是一個分布式協(xié)調(diào)服務(wù),非常適合用來實現(xiàn)分布式鎖。下面我將介紹如何在Spring Boot項目中集成Zookeeper來實現(xiàn)分布式鎖。
1. 添加依賴
首先,在pom.xml中添加必要的依賴:
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.7.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>5.2.0</version>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>5.2.0</version>
</dependency>2. 配置Zookeeper連接
在application.properties或application.yml中配置Zookeeper連接信息:
# Zookeeper配置 zookeeper.address=localhost:2181 zookeeper.session-timeout=5000 zookeeper.connection-timeout=5000
3. 創(chuàng)建Zookeeper配置類
@Configuration
public class ZookeeperConfig {
@Value("${zookeeper.address}")
private String connectString;
@Value("${zookeeper.session-timeout}")
private int sessionTimeout;
@Value("${zookeeper.connection-timeout}")
private int connectionTimeout;
@Bean
public CuratorFramework curatorFramework() {
RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
CuratorFramework client = CuratorFrameworkFactory.builder()
.connectString(connectString)
.sessionTimeoutMs(sessionTimeout)
.connectionTimeoutMs(connectionTimeout)
.retryPolicy(retryPolicy)
.build();
client.start();
return client;
}
}4. 實現(xiàn)分布式鎖工具類
@Component
public class ZookeeperDistributedLock {
private final CuratorFramework client;
private static final String LOCK_ROOT_PATH = "/locks";
public ZookeeperDistributedLock(CuratorFramework client) {
this.client = client;
}
/**
* 獲取互斥鎖
* @param lockPath 鎖路徑
* @param timeout 超時時間(毫秒)
* @return 鎖對象
*/
public InterProcessMutex acquireMutex(String lockPath, long timeout) throws Exception {
String path = LOCK_ROOT_PATH + "/" + lockPath;
InterProcessMutex mutex = new InterProcessMutex(client, path);
if (mutex.acquire(timeout, TimeUnit.MILLISECONDS)) {
return mutex;
}
return null;
}
/**
* 釋放鎖
* @param mutex 鎖對象
*/
public void releaseMutex(InterProcessMutex mutex) {
try {
if (mutex != null && mutex.isAcquiredInThisProcess()) {
mutex.release();
}
} catch (Exception e) {
throw new RuntimeException("釋放鎖失敗", e);
}
}
}5. 使用分布式鎖
在業(yè)務(wù)代碼中使用分布式鎖:
@Service
public class OrderService {
@Autowired
private ZookeeperDistributedLock distributedLock;
public void createOrder() {
InterProcessMutex lock = null;
try {
// 獲取鎖,設(shè)置超時時間5秒
lock = distributedLock.acquireMutex("order-create", 5000);
if (lock != null) {
// 獲取鎖成功,執(zhí)行業(yè)務(wù)邏輯
System.out.println("獲取鎖成功,開始處理業(yè)務(wù)");
// 模擬業(yè)務(wù)處理
Thread.sleep(2000);
System.out.println("業(yè)務(wù)處理完成");
} else {
System.out.println("獲取鎖失敗,可能有其他實例正在處理");
}
} catch (Exception e) {
e.printStackTrace();
} finally {
// 釋放鎖
if (lock != null) {
distributedLock.releaseMutex(lock);
}
}
}
}6. 測試分布式鎖
可以啟動多個Spring Boot實例來測試分布式鎖的效果:
@RestController
@RequestMapping("/order")
public class OrderController {
@Autowired
private OrderService orderService;
@GetMapping("/create")
public String createOrder() {
orderService.createOrder();
return "訂單創(chuàng)建請求已提交";
}
}實現(xiàn)原理說明
臨時順序節(jié)點:Zookeeper的分布式鎖實際上是利用了臨時順序節(jié)點的特性
鎖獲取:
- 每個客戶端在指定的鎖路徑下創(chuàng)建臨時順序節(jié)點
- 判斷自己創(chuàng)建的節(jié)點是否是當(dāng)前最小的節(jié)點,如果是則獲取鎖
- 如果不是則監(jiān)聽前一個節(jié)點的刪除事件
鎖釋放:
- 任務(wù)完成后刪除自己創(chuàng)建的節(jié)點
- 下一個節(jié)點會收到通知并獲取鎖
注意事項
- 連接管理:確保Zookeeper客戶端連接的正確管理和異常處理
- 鎖超時:設(shè)置合理的鎖超時時間,避免死鎖
- 鎖釋放:務(wù)必在finally塊中釋放鎖,防止鎖泄漏
- 重試機(jī)制:網(wǎng)絡(luò)不穩(wěn)定時需要有合理的重試機(jī)制
- 鎖粒度:根據(jù)業(yè)務(wù)需求設(shè)計合理的鎖粒度
以上實現(xiàn)使用了Curator框架,它封裝了Zookeeper的復(fù)雜操作,提供了更簡單易用的API,特別是它的InterProcessMutex類已經(jīng)實現(xiàn)了分布式鎖的核心邏輯。
到此這篇關(guān)于SpringBoot使用Zookeeper實現(xiàn)分布式鎖的實現(xiàn)示例的文章就介紹到這了,更多相關(guān)SpringBoot Zookeeper分布式鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
springboot項目中的bootstrap.yml配置不生效的原因及解決(沒有自動提示)
新創(chuàng)建一個 springboot項目,添加了 bootstrap.yml 文件,發(fā)現(xiàn)文件并沒有如預(yù)期變成綠色葉子,編寫的時候也沒有自動提示,啟動的時候,發(fā)現(xiàn)端口是8080,由此發(fā)現(xiàn)配置并沒有生效,所以本文給大家講解了springboot項目中的bootstrap.yml配置不生效的原因及解決2024-01-01
SpringBoot 添加JSP 支持并附帶在IDEA下創(chuàng)建JSP文件【測試無誤】
這篇文章主要介紹了SpringBoot 添加JSP 支持并附帶在IDEA下創(chuàng)建JSP文件的相關(guān)知識,感興趣的朋友跟隨腳本之家小編一起學(xué)習(xí)吧2018-05-05
springboot Actuator的指標(biāo)監(jiān)控可視化功能詳解
SpringBoot Actuator是springboot為簡化我們對微服務(wù)項目的監(jiān)控功能抽取出來的模塊,使得我們每個微服務(wù)快速引用即可獲得生產(chǎn)界別的應(yīng)用監(jiān)控、審計等功能。這篇文章主要介紹了springboot Actuator的指標(biāo)監(jiān)控可視化,需要的朋友可以參考下2021-08-08
SpringBoot連接MySql數(shù)據(jù)庫的原理及代碼示例
SpringBoot是一款流行的Java開發(fā)框架,它可以輕松地連接各種類型的數(shù)據(jù)庫,包括關(guān)系型數(shù)據(jù)庫和非關(guān)系型數(shù)據(jù)庫,本文將介紹SpringBoot是如何連接數(shù)據(jù)庫的,包括其原理和代碼示例,需要的朋友可以參考下2023-07-07
SpringBoot使用@valid進(jìn)行參數(shù)校驗的流程步驟
SpringBoot 提供了一種方便的方式來進(jìn)行參數(shù)校驗:使用 Hibernate Validator,Spring Boot 提供了一種方便的方式來進(jìn)行參數(shù)校驗:使用 Hibernate Validator,所以本文給大家介紹了SpringBoot使用@valid進(jìn)行參數(shù)校驗的流程步驟,需要的朋友可以參考下2023-09-09
解決java啟動時報線程占用報錯:Exception?in?thread?“Thread-14“?java.ne
這篇文章主要給大家介紹了關(guān)于解決java啟動時報線程占用:Exception?in?thread?“Thread-14“?java.net.BindException:?Address?already?in?use:?bind的相關(guān)資料,文中將解決的辦法介紹的非常詳細(xì),需要的朋友可以參考下2023-04-04

