使用redisson做分布式鎖
分布式鎖
在java中單體應用中,我們如果想要保證一個接口或者服務、方法當下只有一個線程在運行,我們可以通過JDK提供的Lock、Semaphore、同步鎖等多種方式實現只有一個線程在運行。
在微服務系統中,我們的單體應用會變成多個節點,只靠JDK本身的鎖只能控制一個節點的運行,所以我們需要一個可以控制全局的鎖來控制系統的運行,這就是所謂的分布式鎖。
Zk redis 等中間件都可以做分布式鎖,優缺點也各不相同,在我們現在的系統中zk的直接操作還是比較少,更多的是作為dubbo的服務信息儲存,所以用Redis做鎖的載體。
Redisson是我國的一位大牛寫的一個框架,可以使用 redis做類似JDK的全局隊列、鎖、集合等N多封裝好的東西,同時也是redis官方推薦的框架。官方文檔地址:
https://github.com/redisson/redisson/wiki
這個主要是入門。
我們的SpringBoot 版本是 1.5.8 ,首先引入SpringBoot starter的依賴,如下:
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson-spring-boot-starter</artifactId>
<version>2.15.1</version>
</dependency>
Application.yml 中的Redis配置不需要改變,與spring系統兼容,直接可以在代碼中使用redisson的api了。
代碼:
@Autowired RedissonClient redissonClient; @Valid @ApiOperation(value = "測試接口", notes = "通過接口 ,對測試服務連通性", httpMethod = "POST", produces = MediaType.APPLICATION_JSON_UTF8_VALUE) @RequestMapping(value = "test", method = RequestMethod.POST) public Response<Void> test() { RLock rLock = redissonClient.getLock("test1"); rLock.lock(); try { Thread.sleep(1000l); } catch (InterruptedException e) { e.printStackTrace(); } if (log.isDebugEnabled()) { log.debug("test welcome........."); } rLock.unlock(); return Response.success("響應成功"); }
我本來使用了最新版的starter但是發現有reactor的東西,造成了啟動報錯,后來去maven倉庫翻了一下,發現2.15.1之后的版本,用的都是2.0以后的springBoot,那2.0之后的用的都是Spring 5的版本,所以往后推,看到2.15.1依然是SpringBoot1.5.X 系列的,
所以使用這個版本,沒有報錯。
這個版本沒有redLock,不過無所謂了,應該沒啥問題,沒那么大的並發,另外,測試過程中,發現那個tryLock有點兒坑,獲取鎖的時間,沒什么用,后續的代碼還是可以執行,執行完成后會報錯。我們應該會直接用Lock。
所謂的redLock就是 Redis主節點沒有寫到從節點的時候,另外一個應用的節點去redis同時查看這個鎖是否存在,造成死鎖,或者沒有保證鎖的安全性(題外話,網上有很多資料)
|