学习本篇之前,可以先看下文章 什么是分布式锁,了解下基本概念。

之前都是手写一个分布式锁,其实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实现分布式锁的更多相关文章

  1. 分布式缓存技术redis学习系列(五)——redis实战(redis与spring整合,分布式锁实现)

    本文是redis学习系列的第五篇,点击下面链接可回看系列文章 <redis简介以及linux上的安装> <详细讲解redis数据结构(内存模型)以及常用命令> <redi ...

  2. spring boot redis分布式锁

    随着现在分布式架构越来越盛行,在很多场景下需要使用到分布式锁.分布式锁的实现有很多种,比如基于数据库. zookeeper 等,本文主要介绍使用 Redis 做分布式锁的方式,并封装成spring b ...

  3. 分布式缓存技术redis系列(五)——redis实战(redis与spring整合,分布式锁实现)

    本文是redis学习系列的第五篇,点击下面链接可回看系列文章 <redis简介以及linux上的安装> <详细讲解redis数据结构(内存模型)以及常用命令> <redi ...

  4. spring boot redis分布式锁 (转)

    一. Redis 分布式锁的实现以及存在的问题 锁是针对某个资源,保证其访问的互斥性,在实际使用当中,这个资源一般是一个字符串.使用 Redis 实现锁,主要是将资源放到 Redis 当中,利用其原子 ...

  5. Spring Boot (33) 分布式锁

    上一篇中使用的Guava Cache,如果在集群中就不可以用了,需要借助Redis.Zookeeper之类的中间件实现分布式锁. 导入依赖 在pom.xml中需要添加的依赖包:stater-web.s ...

  6. redis系列之5----redis实战(redis与spring整合,分布式锁实现)

    本文是redis学习系列的第五篇,点击下面链接可回看系列文章 <redis简介以及linux上的安装> <详细讲解redis数据结构(内存模型)以及常用命令> <redi ...

  7. 使用Redisson实现分布式锁,Spring AOP简化之

    源码 Redisson概述 Redisson是一个在Redis的基础上实现的Java驻内存数据网格(In-Memory Data Grid).它不仅提供了一系列的分布式的Java常用对象,还提供了许多 ...

  8. spring boot 利用redisson实现redis的分布式锁

    原文:http://liaoke0123.iteye.com/blog/2375469 利用redis实现分布式锁,网上搜索的大部分是使用java jedis实现的. redis官方推荐的分布式锁实现 ...

  9. SpringBoot进阶教程(二十七)整合Redis之分布式锁

    在之前的一篇文章(<Java分布式锁,搞懂分布式锁实现看这篇文章就对了>),已经介绍过几种java分布式锁,今天来个Redis分布式锁的demo.redis 现在已经成为系统缓存的必备组件 ...

随机推荐

  1. 在linux中文件的权限讲解

    1.d:directory(目录): 表示这个文件是个目录,其他的还有f(file文件)等等: 2.r:read(可读) 3.w:write(可写) 4 x :execute(可执行) 一般Linux ...

  2. sql 百万级或千万级数据分页处理

    笔记来源 https://blog.csdn.net/zhenyuanjie/article/details/7778102

  3. linux 基础 文件系统 用户权限

    描述Linux系统的启动过程? 1.开机自检 BIOS 2.MBR引导 3.GRUB菜单 4.加载内核 5.运行init进程 6.从/etc/inittab读取运行级别 7.根据/etc/rc.sys ...

  4. LVS、Nginx 及 HAProxy 工作原理

    当前大多数的互联网系统都使用了服务器集群技术,集群是将相同服务部署在多台服务器上构成一个集群整体对外提供服务,这些集群可以是 Web 应用服务器集群,也可以是数据库服务器集群,还可以是分布式缓存服务器 ...

  5. 1-学习tecplot360

    FETRIANGLE(3节点三角形), FEQUADRILATERAL(4节点四边形),FETETRAHEDRON(4节点四面体), FEBRICK(8节点六面体) 参考:https://wenku. ...

  6. UVaLive 4064 Magnetic Train Tracks (极角排序)

    题意:给定 n 个不三点共线的点,然后问你能组成多少锐角或者直角三角形. 析:可以反过来求,求有多少个钝角三角形,然后再用总的减去,直接求肯定会超时,但是可以枚举每个点,以该点为钝角的那个顶点,然后再 ...

  7. 学以致用二十四-----shell脚本中的列表及space

    1.接触列表的概念是在pyhon中,殊不知在shell中也是有列表的. 如: 结果 列表的下标和python中一样,也是以0开头 注意 list 和list2 的区别   一个是用括号括起来,一个是用 ...

  8. Centos6.5安装中文支持和中文输入法

     先来讲中文支持:    之前在网上查了不少资料,很多网友在网上都说,在shell命令下输入: # vi /etc/sysconfig/i18n 然后修改LANG="en_US.UTF-8& ...

  9. 背水一战 Windows 10 (64) - 控件(WebView): 加载指定 HttpMethod 的请求, 自定义请求的 http header, app 与 js 的交互

    [源码下载] 背水一战 Windows 10 (64) - 控件(WebView): 加载指定 HttpMethod 的请求, 自定义请求的 http header, app 与 js 的交互 作者: ...

  10. 剑指offer编程题Java实现——面试题14调整数组顺序使奇数位于偶数之前

    题目: 输入一个整数数组,实现一个函数来调整该数组中数组的顺序,使得所有的奇数位于数组的前半部分,偶数位于数组的后半部分. 解题思路:数组中维护两个指针,第一个指针初始化时候指向数组头部,第二个指针初 ...