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 现在已经成为系统缓存的必备组件 ...
随机推荐
- codeforces 508B
B. New Year Permutation time limit per test 2 seconds memory limit per test 256 megabytes input stan ...
- HDU 1171 01背包
http://acm.hdu.edu.cn/showproblem.php?pid=1171 基础的01背包,求出总值sum,背包体积即为sum/2 #include<stdio.h> # ...
- 添加自己的component
在之前讲解esp-idf的文件结构时,曾经讲过component是esp-idf集成的功能块,这篇文章就来讲解下,如何在esp-idf 中添加自己的component. STEP1; 创建compon ...
- [au3]批量输入号码程序
批量输入号码程序 这个文件可以随时产生一个剪贴板文字的文本文件,以供其他程序读取. 这个程序修改了许多次了,主要是针对网络延迟的问题. 最终找到了解决方案:探测输入的界面的反馈信息,也就是反馈的颜色. ...
- CentOS6最佳实践
一 安装常用软件 常用目录结构 源文件目录 /application,原包文件及解压文件 如 /application/Python-3.6.0.tgz 软件配置目录 /usr/local/ 如 ...
- 使用 IncrediBuild 提升 VisualStudio 编译速度
我现在有一个 100M 的代码,需要快速去编译他,我寻找了很多方法,本文记录我找到的 IncrediBuild 用于提交编译速度. 如果一个项目存在很多不相互依赖的项目,那么使用 IncrediBui ...
- 【接口时序】5、QSPI Flash的原理与QSPI时序的Verilog实现
一. 软件平台与硬件平台 软件平台: 1.操作系统:Windows-8.1 2.开发套件:ISE14.7 3.仿真工具:ModelSim-10.4-SE 4.Matlab版本:Matlab2014b/ ...
- Hibernate入门1 - Hibernate概述及第一个小例子
一.什么是ORM? ORM,即Object Relational Mapping.我们知道,利用面向对象的思想编写的数据库应用程序最终都是把对象信息保存在关系型数据库中,于是需要编写与底层数据库相关的 ...
- PHP利用Session实现上传进度
实现文件上传进度条基本是依靠JS插件或HTML5的File API来完成,其实PHP配合ajax也能实现此功能. PHP手册对于session上传进度是这么介绍的: 当 session.upload_ ...
- 哥们,你真以为你会做这道JVM面试题?
有关Java虚拟机类加载机制相关的文章一搜一大把,笔者这里也不必再赘述一遍了. 笔者这里捞出一道code题要各位大佬来把玩把玩,如果你一眼就看出了端倪,那么恭喜你,你可以下山了: public cla ...