Spring Integration實(shí)現(xiàn)分布式鎖
點(diǎn)擊上方藍(lán)色字體,選擇“標(biāo)星公眾號(hào)”
優(yōu)質(zhì)文章,第一時(shí)間送達(dá)
? 作者?|??僅此而已-遠(yuǎn)方
來源 |? urlify.cn/b2umMv
66套java從入門到精通實(shí)戰(zhàn)課程分享?
學(xué)習(xí)本篇之前,可以先看下文章?什么是分布式鎖,了解下基本概念。
之前都是手寫一個(gè)分布式鎖,其實(shí)Spring早就提供了分布式鎖的實(shí)現(xiàn)。早期,分布式鎖的相關(guān)代碼存在于Spring Cloud的子項(xiàng)目Spring Cloud Cluster中,后來被遷移到Spring Integration中。
Spring Integration提供的全局鎖,目前為這幾種存儲(chǔ)提供了實(shí)現(xiàn):Gemfire、JDBC、Redis、Zookeeper
它們使用相同的API抽象--這正是Spring最擅長(zhǎng)的。這意味著,不論使用哪種存儲(chǔ),你的編碼體驗(yàn)都是一樣的,有一天想更換實(shí)現(xiàn),只需要修改依賴和配置就可以了,無需修改代碼
?
下面以Redis為例,講解Spring Integration如何使用分布式鎖。
1、增加依賴:
????
????<groupId>org.springframework.bootgroupId>
????<artifactId>spring-boot-starter-integrationartifactId>
dependency>
????
????<groupId>org.springframework.integrationgroupId>
????<artifactId>spring-integration-redisartifactId>
dependency>
????
????<groupId>org.springframework.bootgroupId>
????<artifactId>spring-boot-starter-data-redisartifactId>
dependency>2、配置文件增加redis配置:
spring:
??redis:
????port:?6379
????host:?localhost3、增加RedisLock的配置類:
@Configuration
public?class?RedisLockConfiguration?{
????@Bean
????public?RedisLockRegistry redisLockRegistry(RedisConnectionFactory redisConnectionFactory)?{
????????return?new?RedisLockRegistry(redisConnectionFactory, "spring-cloud");
????}
}4、增加測(cè)試方法:
@RestController
@RequestMapping("redis")
public?class?RedisController?{
????@Autowired
????private?RedisLockRegistry redisLockRegistry;
????private?int?num = 20;
????/**
?????* 測(cè)試redis分布式鎖(沒有鎖)
?????*/
????@GetMapping("testUnLock")
????public?void?testUnLock() throws InterruptedException {
????????String s = Thread.currentThread().getName();
????????if?(num > 0) {
????????????System.out.println(s + "排號(hào)成功,號(hào)碼是:"?+ num);
????????????num--;
????????} else?{
????????????System.out.println(s + "排號(hào)失敗,號(hào)碼已經(jīng)被搶光");
????????}
????}
????/**
?????* 測(cè)試redis分布式鎖(有鎖)
?????*/
????@GetMapping("testLock")
????public?void?testLock() throws InterruptedException {
????????Lock lock?= redisLockRegistry.obtain("lock");
????????boolean isLock = lock.tryLock(1, TimeUnit.SECONDS);
????????String s = Thread.currentThread().getName();
????????if?(num > 0?&& isLock) {
????????????System.out.println(s + "排號(hào)成功,號(hào)碼是:"?+ num);
????????????num--;
????????} else?{
????????????System.out.println(s + "排號(hào)失敗,號(hào)碼已經(jīng)被搶光");
????????}
????????lock.unlock();
????}
}使用壓測(cè)工具(如:JMeter),開啟25個(gè)線程,循環(huán)一次:

先測(cè)試一下沒有加鎖,會(huì)出現(xiàn)什么結(jié)果。請(qǐng)求 http://localhost:18081/redis/testUnLock:
http-nio-18081-exec-22排號(hào)成功,號(hào)碼是:20
http-nio-18081-exec-28排號(hào)成功,號(hào)碼是:19
http-nio-18081-exec-16排號(hào)成功,號(hào)碼是:18
http-nio-18081-exec-30排號(hào)成功,號(hào)碼是:17
http-nio-18081-exec-26排號(hào)成功,號(hào)碼是:16
http-nio-18081-exec-15排號(hào)成功,號(hào)碼是:15
http-nio-18081-exec-15排號(hào)成功,號(hào)碼是:14
http-nio-18081-exec-3排號(hào)成功,號(hào)碼是:14
http-nio-18081-exec-26排號(hào)成功,號(hào)碼是:12
http-nio-18081-exec-15排號(hào)成功,號(hào)碼是:11
http-nio-18081-exec-3排號(hào)成功,號(hào)碼是:10
http-nio-18081-exec-15排號(hào)成功,號(hào)碼是:9
http-nio-18081-exec-30排號(hào)成功,號(hào)碼是:8
http-nio-18081-exec-26排號(hào)成功,號(hào)碼是:7
http-nio-18081-exec-3排號(hào)成功,號(hào)碼是:6
http-nio-18081-exec-15排號(hào)成功,號(hào)碼是:5
http-nio-18081-exec-3排號(hào)成功,號(hào)碼是:4
http-nio-18081-exec-26排號(hào)成功,號(hào)碼是:3
http-nio-18081-exec-15排號(hào)成功,號(hào)碼是:2
http-nio-18081-exec-3排號(hào)成功,號(hào)碼是:1
http-nio-18081-exec-30排號(hào)失敗,號(hào)碼已經(jīng)被搶光
http-nio-18081-exec-22排號(hào)成功,號(hào)碼是:14
http-nio-18081-exec-28排號(hào)成功,號(hào)碼是:14
http-nio-18081-exec-15排號(hào)成功,號(hào)碼是:1
http-nio-18081-exec-16排號(hào)成功,號(hào)碼是:12從上面結(jié)果可以看到,num變量的有些值被多個(gè)線程同時(shí)獲取,導(dǎo)致20個(gè)號(hào)被24個(gè)線程獲取
再來試下加鎖的,請(qǐng)求 http://localhost:18081/redis/testLock:
http-nio-18081-exec-2排號(hào)成功,號(hào)碼是:20
http-nio-18081-exec-142排號(hào)成功,號(hào)碼是:19
http-nio-18081-exec-141排號(hào)成功,號(hào)碼是:18
http-nio-18081-exec-171排號(hào)成功,號(hào)碼是:17
http-nio-18081-exec-152排號(hào)成功,號(hào)碼是:16
http-nio-18081-exec-159排號(hào)成功,號(hào)碼是:15
http-nio-18081-exec-154排號(hào)成功,號(hào)碼是:14
http-nio-18081-exec-156排號(hào)成功,號(hào)碼是:13
http-nio-18081-exec-142排號(hào)成功,號(hào)碼是:12
http-nio-18081-exec-158排號(hào)成功,號(hào)碼是:11
http-nio-18081-exec-172排號(hào)成功,號(hào)碼是:10
http-nio-18081-exec-161排號(hào)成功,號(hào)碼是:9
http-nio-18081-exec-160排號(hào)成功,號(hào)碼是:8
http-nio-18081-exec-164排號(hào)成功,號(hào)碼是:7
http-nio-18081-exec-162排號(hào)成功,號(hào)碼是:6
http-nio-18081-exec-171排號(hào)成功,號(hào)碼是:5
http-nio-18081-exec-170排號(hào)成功,號(hào)碼是:4
http-nio-18081-exec-152排號(hào)成功,號(hào)碼是:3
http-nio-18081-exec-165排號(hào)成功,號(hào)碼是:2
http-nio-18081-exec-157排號(hào)成功,號(hào)碼是:1
http-nio-18081-exec-168排號(hào)失敗,號(hào)碼已經(jīng)被搶光
http-nio-18081-exec-159排號(hào)失敗,號(hào)碼已經(jīng)被搶光
http-nio-18081-exec-166排號(hào)失敗,號(hào)碼已經(jīng)被搶光
http-nio-18081-exec-163排號(hào)失敗,號(hào)碼已經(jīng)被搶光
http-nio-18081-exec-177排號(hào)失敗,號(hào)碼已經(jīng)被搶光從上面結(jié)果可以看到,20個(gè)號(hào)挨個(gè)被20個(gè)線程獲取,剩下5個(gè)線程將獲取不到。說明鎖起作用了~


??? ?
感謝點(diǎn)贊支持下哈?
