在微服務中不少狀況下須要使用到分佈式鎖功能,而目前比較常見的方案是經過Redis來實現分佈式鎖,網上關於分佈式鎖的實現方式有不少,早期主要是基於Redisson等客戶端,但在Spring Boot2.x以上版本中使用Redis時,其客戶端庫已經默認使用lettuce。 因此本文將直接介紹在Spring Boot2.x以上項目中快速使用Redis分佈式鎖的功能的方法,但願可以更新你的知識庫!redis
實際上Redis服務自己並不提供分佈式鎖這樣的機制,可是做爲全局Key-Value存儲系統,客戶端能夠利用Redis提供的基本功能並經過必定的算法設計來實現分佈式鎖功能。目前已有很多博客文章及代碼庫描述瞭如何使用Redis來實現分佈式鎖,可是許多實現相對比較簡單,安全性也比較低。在Redis的官方文檔中推薦了一種叫作RedLock的算法來實現基於Redis的分佈式鎖功能,現階段已存在基於該算法的多種語言版本的Redis客戶端實現庫。其中Java領域最爲知名的是Redisson庫。但因爲Redisson不只實現了分佈式鎖功能,還額外實現了一套Redis分佈式數據結構,所以會顯得比較重,加上最新的基於Spring Boot.2.x以上版本使用Redis時,其客戶端庫已經默認使用了lettuce(比Redisson、Jedis線程更安全、更輕量級的一種Java Redis客戶端庫)的封裝,因此爲了更加符合微服務場景下的使用,在實踐中每每會選擇基於RedLock算法自行實現分佈式鎖。算法
本案例也將演示如何RedLock算法來實現Redis分佈式鎖功能,不過在此以前讓咱們先來看看RedLock算法是如何運行的,示意圖以下:spring
以上就是實現Redis分佈式鎖官方推薦的RedLock算法邏輯,它是一種多節點Redis的分佈式鎖算法,能夠有效防止單節點故障問題。其執行步驟說明以下:安全
實現上述算法的Redis客戶端能夠基本上保證分佈式鎖的有效性及安全性的幾個基本特性要求:bash
經過前面內容的描述,相信你對實現Redis分佈式鎖的基本算法應該有了必定的認識和理解。而在實踐的過程當中能夠依據該算法自行定製實現,但實際上Spring早就提供了基於該算法的Redis的分佈式鎖的實現。其具體使用步驟以下:數據結構
1)在工程pom.xml文件中引入Spring Integration依賴,代碼以下:分佈式
<!-- spring integration -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<!-- spring integration與redis結合,實現redis分佈式鎖 -->
<dependency>
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-redis</artifactId>
</dependency>
複製代碼
目前Spring所提供的分佈式鎖相關的代碼被遷移在Spring Integration子項目中,因此這裏引入其相關依賴。ide
2)編寫RedisLock的配置類,代碼以下:spring-boot
@Configuration
public class RedisLockConfiguration {
@Bean
public RedisLockRegistry redisLockRegistry(RedisConnectionFactory redisConnectionFactory) {
return new RedisLockRegistry(redisConnectionFactory, "payment");
}
}
複製代碼
以上配置代碼加載的前提在於應用已經集成了Redis服務訪問連接信息,具體Spring Boot項目集成Redis訪問的方式比較簡單能夠參考其餘資料。微服務
3)分佈式鎖的具體使用方式,代碼片斷以下:
/**
* 引入Redis分佈式鎖依賴組件
*/
@Autowired
private RedisLockRegistry redisLockRegistry;
@Override
public UnifiedPayBO unifiedPay(UnifiedPayDTO unifiedPayDTO) {
...
//建立Redis分佈式鎖
Lock lock = redisLockRegistry.obtain(redisLockPrefix + unifiedPayDTO.getOrderId());
try {
//嘗試獲取鎖
boolean isLock = lock.tryLock(1, TimeUnit.SECONDS);
if (isLock) {
//執行業務邏輯
...
}
} catch (InterruptedException e) {
e.printStackTrace();
} finally {
//釋放分佈式鎖
lock.unlock();
}
...
}
複製代碼
上述代碼爲訂單防重時使用Redis分佈鎖的示例代碼,經過依賴注入RedisLockRegistry實例來實現分佈式鎖的相關操做,例如obtain()方法建立鎖、tryLock()持有鎖及unlock()釋放鎖等。
歡迎你們關注我新開通的公衆號【風平浪靜如碼】,海量Java相關文章,學習資料都會在裏面更新,整理的資料也會放在裏面。
以爲寫的還不錯的就點個贊,加個關注唄!點關注,不迷路,持續更新!!!