絕對乾貨:利用redisson完成分散式鎖功能

絕對乾貨:利用redisson完成分散式鎖功能

在單體架構中,我們使用synchronize或者Lock就能完成上鎖同步的操作,但是這些在分散式,微服務的今天,失去了作用。

分散式鎖的實現一般有三種解決方案:

基於資料庫表實現

基於快取實現,比如redis

基於zookeeper實現

那麼利用redisson就是基於redis來實現的分散式鎖功能。

什麼是redisson

官網:https://redisson。org

從首頁的,我們可以大致看出redisson可以實現很多東西,在redisson的基礎上,redisson做了超多的封裝。

絕對乾貨:利用redisson完成分散式鎖功能

redisson可以完成很多功能,比如快取各種佇列,包括map等這些資料結構,也能完成分散式任務排程,還能完成今天我們說的分散式鎖的功能。總之一句話:Redisson是非常強大。

利用redisson完成分散式鎖功能

Quick start

我們先看看官網上是如何介紹快速使用redisson。

絕對乾貨:利用redisson完成分散式鎖功能

絕對乾貨:利用redisson完成分散式鎖功能

以上是官網的使用介紹。那麼今天以官網的方式來實現我們自己的分散式鎖

一,引入maven依賴

org。redisson redisson 3。11。5

二,建立分散式鎖工具類

@Componentpublic class DistributedLockerUtil {

private RedissonClient redissonClient; @PostConstruct private void init() { if(redissonClient != null){ return; } //配置config,如果是單機版的redis,那麼就是使用config。useSingleServer() //如果是叢集,那麼請使用config。useClusterServers() Config config = new Config(); config。useSingleServer()。setAddress(“redis://10。10。100。116:6379”); redissonClient = Redisson。create(config); } /** * 獲取RedissonClient * @return */ public RedissonClient getRedissonClient(){ return this。redissonClient; } /** * 加鎖 * @return */ public void lock(String lockKey){ redissonClient。getLock(lockKey)。lock(); } /** * 釋放鎖 */ public void unLock(String lockKey){ redissonClient。getLock(lockKey)。unlock(); } /** * 帶超時的加鎖 * @param lockKey * @param tomeout 秒為單位 */ public void lock(String lockKey, Long tomeout){ redissonClient。getLock(lockKey)。lock(tomeout, TimeUnit。SECONDS); } /** * 帶超市的加鎖 * @param lockKey * @param unit 時間單位 * @param tomeout */ public void lock(String lockKey, TimeUnit unit,Long tomeout){ redissonClient。getLock(lockKey)。lock(tomeout, unit); } /** * 嘗試獲取鎖 * @param lockKey * @return */ public boolean tryLock(String lockKey){ return redissonClient。getLock(lockKey)。tryLock(); } /** * 嘗試獲取鎖 * @param lockKey * @param timeout 嘗試等待多少秒時間 * @return * @throws InterruptedException */ public boolean tryLock(String lockKey,Long timeout) throws InterruptedException { return redissonClient。getLock(lockKey)。tryLock(timeout, TimeUnit。SECONDS); } /** * * @param lockKey * @param unit 時間單位 * @param waitTime 最多等待多久時間 * @param leaseTime 上鎖後多久釋放 * @return */ public boolean tryLock(String lockKey, TimeUnit unit, int waitTime, int leaseTime) throws InterruptedException { return redissonClient。getLock(lockKey)。tryLock(waitTime,leaseTime,unit); } }

建立好之後,就可以使用以上util進行分散式鎖的操作

三,新建controller

簡單點,我們實現增加庫存的業務。每次走進controller增加庫存的方法,我們就+1。為了演示效果,其中addStockYaGao方法不加分散式鎖,而addStockYaShua加入分散式鎖。

@RequestMapping(“/stock”) @RestController public class StockController { @Autowired private StockService stockService; @Autowired private DistributedLockerUtil distributedLockerUtil; @GetMapping(“/addStockYaGao”) public String addStockYaGao(){ Stock stock = stockService。getOne(1); stock。setCount(stock。getCount() + 1); stockService。save(stock); return “增加牙膏成功”; } @GetMapping(“/addStockYaShua”) public String addStockYaShua(){ try { distributedLockerUtil。lock(“addStock”); Stock stock = stockService。getOne(2); stock。setCount(stock。getCount() + 1); stockService。save(stock); return “增加牙刷成功”; }catch (Exception e){ e。printStackTrace(); return “增加牙刷失敗”; }finally { distributedLockerUtil。unLock(“addStock”); } } }

四,表資料

原始資料如下:

絕對乾貨:利用redisson完成分散式鎖功能

表對應實體類以及dao,service這裡就不貼出來了。

五,JMeter測試效果

測試併發引數:

絕對乾貨:利用redisson完成分散式鎖功能

先對不加鎖的addStockYaGao進行測試,

絕對乾貨:利用redisson完成分散式鎖功能

結果:

絕對乾貨:利用redisson完成分散式鎖功能

明顯資料不對,300個使用者請求,按理來說最後的結果應該是300

再對加鎖的addStockYaShua進行測試

絕對乾貨:利用redisson完成分散式鎖功能

結果:

絕對乾貨:利用redisson完成分散式鎖功能

資料正確,更新到了300

總結,使用redisson完成分散式鎖功能還是很簡單的,大家get得到了嗎?

本人水平有限,難免有錯誤或遺漏之處,望大家指正和諒解,提出寶貴意見,願與之交流。