Spring Integration实现分布式锁
学习本篇之前,可以先看下文章 什么是分布式锁,了解下基本概念。
之前都是手写一个分布式锁,其实Spring早就提供了分布式锁的实现。早期,分布式锁的相关代码存在于Spring Cloud的子项目Spring Cloud Cluster中,后来被迁移到Spring Integration中。
Spring Integration提供的全局锁,目前为这几种存储提供了实现:Gemfire、JDBC、Redis、Zookeeper
它们使用相同的API抽象--这正是Spring最擅长的。这意味着,不论使用哪种存储,你的编码体验都是一样的,有一天想更换实现,只需要修改依赖和配置就可以了,无需修改代码
下面以Redis为例,讲解Spring Integration如何使用分布式锁。
1、增加依赖:
<dependency>
<!-- spring integration -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-integration</artifactId>
</dependency>
<dependency>
<!-- spring integration与redis结合,实现redis分布式锁 -->
<groupId>org.springframework.integration</groupId>
<artifactId>spring-integration-redis</artifactId>
</dependency>
<dependency>
<!-- redis -->
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
2、配置文件增加redis配置:
spring:
redis:
port:
host: localhost
3、增加RedisLock的配置类:
@Configuration
public class RedisLockConfiguration { @Bean
public RedisLockRegistry redisLockRegistry(RedisConnectionFactory redisConnectionFactory) {
return new RedisLockRegistry(redisConnectionFactory, "spring-cloud");
} }
4、增加测试方法:
@RestController
@RequestMapping("redis")
public class RedisController { @Autowired
private RedisLockRegistry redisLockRegistry; private int num = ; /**
* 测试redis分布式锁(没有锁)
*/
@GetMapping("testUnLock")
public void testUnLock() throws InterruptedException {
String s = Thread.currentThread().getName();
if (num > ) {
System.out.println(s + "排号成功,号码是:" + num);
num--;
} else {
System.out.println(s + "排号失败,号码已经被抢光");
}
} /**
* 测试redis分布式锁(有锁)
*/
@GetMapping("testLock")
public void testLock() throws InterruptedException {
Lock lock = redisLockRegistry.obtain("lock");
boolean isLock = lock.tryLock(, TimeUnit.SECONDS);
String s = Thread.currentThread().getName();
if (num > && isLock) {
System.out.println(s + "排号成功,号码是:" + num);
num--;
} else {
System.out.println(s + "排号失败,号码已经被抢光");
}
lock.unlock();
} }
使用压测工具(如:JMeter),开启25个线程,循环一次:

先测试一下没有加锁,会出现什么结果。请求 http://localhost:18081/redis/testUnLock:
http-nio--exec-22排号成功,号码是:
http-nio--exec-28排号成功,号码是:
http-nio--exec-16排号成功,号码是:
http-nio--exec-30排号成功,号码是:
http-nio--exec-26排号成功,号码是:
http-nio--exec-15排号成功,号码是:
http-nio--exec-15排号成功,号码是:
http-nio--exec-3排号成功,号码是:
http-nio--exec-26排号成功,号码是:
http-nio--exec-15排号成功,号码是:
http-nio--exec-3排号成功,号码是:
http-nio--exec-15排号成功,号码是:
http-nio--exec-30排号成功,号码是:
http-nio--exec-26排号成功,号码是:
http-nio--exec-3排号成功,号码是:
http-nio--exec-15排号成功,号码是:
http-nio--exec-3排号成功,号码是:
http-nio--exec-26排号成功,号码是:
http-nio--exec-15排号成功,号码是:
http-nio--exec-3排号成功,号码是:
http-nio--exec-30排号失败,号码已经被抢光
http-nio--exec-22排号成功,号码是:
http-nio--exec-28排号成功,号码是:
http-nio--exec-15排号成功,号码是:
http-nio--exec-16排号成功,号码是:
从上面结果可以看到,num变量的有些值被多个线程同时获取,导致20个号被24个线程获取
再来试下加锁的,请求 http://localhost:18081/redis/testLock:
http-nio--exec-2排号成功,号码是:
http-nio--exec-142排号成功,号码是:
http-nio--exec-141排号成功,号码是:
http-nio--exec-171排号成功,号码是:
http-nio--exec-152排号成功,号码是:
http-nio--exec-159排号成功,号码是:
http-nio--exec-154排号成功,号码是:
http-nio--exec-156排号成功,号码是:
http-nio--exec-142排号成功,号码是:
http-nio--exec-158排号成功,号码是:
http-nio--exec-172排号成功,号码是:
http-nio--exec-161排号成功,号码是:
http-nio--exec-160排号成功,号码是:
http-nio--exec-164排号成功,号码是:
http-nio--exec-162排号成功,号码是:
http-nio--exec-171排号成功,号码是:
http-nio--exec-170排号成功,号码是:
http-nio--exec-152排号成功,号码是:
http-nio--exec-165排号成功,号码是:
http-nio--exec-157排号成功,号码是:
http-nio--exec-168排号失败,号码已经被抢光
http-nio--exec-159排号失败,号码已经被抢光
http-nio--exec-166排号失败,号码已经被抢光
http-nio--exec-163排号失败,号码已经被抢光
http-nio--exec-177排号失败,号码已经被抢光
从上面结果可以看到,20个号挨个被20个线程获取,剩下5个线程将获取不到。说明锁起作用了~
Spring Integration实现分布式锁的更多相关文章
- 分布式缓存技术redis学习系列(五)——redis实战(redis与spring整合,分布式锁实现)
本文是redis学习系列的第五篇,点击下面链接可回看系列文章 <redis简介以及linux上的安装> <详细讲解redis数据结构(内存模型)以及常用命令> <redi ...
- spring boot redis分布式锁
随着现在分布式架构越来越盛行,在很多场景下需要使用到分布式锁.分布式锁的实现有很多种,比如基于数据库. zookeeper 等,本文主要介绍使用 Redis 做分布式锁的方式,并封装成spring b ...
- 分布式缓存技术redis系列(五)——redis实战(redis与spring整合,分布式锁实现)
本文是redis学习系列的第五篇,点击下面链接可回看系列文章 <redis简介以及linux上的安装> <详细讲解redis数据结构(内存模型)以及常用命令> <redi ...
- spring boot redis分布式锁 (转)
一. Redis 分布式锁的实现以及存在的问题 锁是针对某个资源,保证其访问的互斥性,在实际使用当中,这个资源一般是一个字符串.使用 Redis 实现锁,主要是将资源放到 Redis 当中,利用其原子 ...
- Spring Boot (33) 分布式锁
上一篇中使用的Guava Cache,如果在集群中就不可以用了,需要借助Redis.Zookeeper之类的中间件实现分布式锁. 导入依赖 在pom.xml中需要添加的依赖包:stater-web.s ...
- redis系列之5----redis实战(redis与spring整合,分布式锁实现)
本文是redis学习系列的第五篇,点击下面链接可回看系列文章 <redis简介以及linux上的安装> <详细讲解redis数据结构(内存模型)以及常用命令> <redi ...
- 使用Redisson实现分布式锁,Spring AOP简化之
源码 Redisson概述 Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid).它不仅提供了一系列的分布式的Java常用对象,还提供了许多 ...
- spring boot 利用redisson实现redis的分布式锁
原文:http://liaoke0123.iteye.com/blog/2375469 利用redis实现分布式锁,网上搜索的大部分是使用java jedis实现的. redis官方推荐的分布式锁实现 ...
- SpringBoot进阶教程(二十七)整合Redis之分布式锁
在之前的一篇文章(<Java分布式锁,搞懂分布式锁实现看这篇文章就对了>),已经介绍过几种java分布式锁,今天来个Redis分布式锁的demo.redis 现在已经成为系统缓存的必备组件 ...
随机推荐
- 差分模版题(需理解才明白)AT2442 フェーン現象 (Foehn Phenomena)
https://www.luogu.org/problemnew/show/AT2442 #include <bits/stdc++.h> #define read read() #def ...
- python实现netcat部分功能源代码
#!/opt/local/bin/python2.7 import sys import socket import getopt import threading import subprocess ...
- 51nod1683
代码参考:http://blog.csdn.net/sdfzyhx/article/details/74359927 //dp[i][j][k]表示到了第i列,最下边的点最短路为j,剩下的点之间的关系 ...
- array_flip()函数
array_flip() 函数用于反转/交换数组中所有的键名以及它们关联的键值. array_flip() 函数返回一个反转后的数组,如果同一值出现了多次,则最后一个键名将作为它的值,所有其他的键名都 ...
- MFC TabCtrl 控件修改标签尺寸
注意:无论那种方法,都要先设置Tab控件的Style属性为fixed width. 第一种方法 MFC,tabcontrol控件改变标签大小 - CSDN博客 https://blog.csdn.ne ...
- Two strings 的另一种解法
Two strings 的另一种解法 论文中的解法是离线插入 \(O(\log n)\) 询问 \(O(\log n)\) 的,不过我发现有一种离线插入 \(O(1)\) 询问 \(O(\log n) ...
- JavaScript实现页面显示倒计时功能
下面是用JS中的日期函数和定时器完成的一个倒计时的例子,效果如图: 代码如下: <!DOCTYPE html> <html> <head> <title> ...
- Eclipse 中 SVN 插件的安装与使用
下载和安装SVN插件 插件在线安装 可以选择在线安装插件的方式,就是使用eclipse里Help菜单的“Install New Software”,通过输入SVN地址,直接下载安装到eclipse里. ...
- 功能强大的swiper插件
概述 今天体验了一下swiper,真是太强大了,无论是PC端还是移动端,各种轮播滑块效果随便实现.美中不足的是,有些实现需要自己想办法.下面我记录下我的需求和我的实现,供以后开发时参考,相信对其他人也 ...
- HoloLens开发手记 - 使用Visual Studio Using Visual Studio
不论你是否使用DirectX或Unity来开发全息应用,你都会使用Visual Studio 2015来进行调试和部署应用.在本部分,你将会学习以下内容: 如何通过Visual Studio将你的应用 ...