1 使用Spring Integration实现分布式锁-德赢Vwin官网 网
0
  • 聊天消息
  • 系统消息
  • 评论与回复
登录后你可以
  • 下载海量资料
  • 学习在线课程
  • 观看技术视频
  • 写文章/发帖/加入社区
会员中心
创作中心

完善资料让更多小伙伴认识你,还能领取20积分哦,立即完善>

3天内不再提示

使用Spring Integration实现分布式锁

数据分析与开发 来源:JAVA日知录 作者:飘渺Jam 2022-05-13 15:42 次阅读

概述

提到分布式锁大家都会想到如下两种:

  • 基于Redisson组件,使用redlock算法实现
  • 基于Apache Curator,利用Zookeeper的临时顺序节点模型实现

今天我们来说说第三种,使用Spring Integration实现。

Spring Integration在基于Spring的应用程序中实现轻量级消息传递,并支持通过声明适配器与外部系统集成。

Spring Integration的主要目标是提供一个简单的模型来构建企业集成解决方案,同时保持关注点的分离,这对于生成可维护,可测试的代码至关重要。我们熟知的 Spring Cloud Stream的底层就是Spring Integration。

官方地址:https://github.com/spring-projects/spring-integration

Spring Integration提供的全局锁目前为如下存储提供了实现:

  • Gemfire
  • JDBC
  • Redis
  • Zookeeper

它们使用相同的API抽象,这意味着,不论使用哪种存储,你的编码体验是一样的。试想一下你目前是基于zookeeper实现的分布式锁,哪天你想换成redis的实现,我们只需要修改相关依赖和配置就可以了,无需修改代码。下面是你使用Spring Integration实现分布式锁时需要关注的方法:

方法名 描述
lock() Acquires the lock.加锁,如果已经被其他线程锁住或者当前线程不能获取锁则阻塞
lockInterruptibly() Acquires the lock unless the current thread is interrupted.加锁,除非当前线程被打断。
tryLock() Acquires the lock only if it is free at the time of invocation.尝试加锁,如果已经有其他锁锁住,获取当前线程不能加锁,则返回false,加锁失败;加锁成功则返回true
tryLock(long time, TimeUnit unit) Acquires the lock if it is free within the given waiting time and the current thread has not been interrupted.尝试在指定时间内加锁,如果已经有其他锁锁住,获取当前线程不能加锁,则返回false,加锁失败;加锁成功则返回true
unlock() Releases the lock.解锁

实战

话不多说,我们看看使用Spring Integration如何基于redis和zookeeper快速实现分布式锁,至于Gemfire 和 Jdbc的实现大家自行实践。

基于Redis实现

  • 引入相关组件

	

org.springframework.boot
spring-boot-starter-integration



org.springframework.integration
spring-integration-redis



org.springframework.boot
spring-boot-starter-data-redis
  • 在application.yml中添加redis的配置

	
spring:
redis:
host:172.31.0.149
port:7111
  • 建立配置类,注入RedisLockRegistry

	
@Configuration
publicclassRedisLockConfiguration{

@Bean
publicRedisLockRegistryredisLockRegistry(RedisConnectionFactoryredisConnectionFactory){
returnnewRedisLockRegistry(redisConnectionFactory,"redis-lock");
}

}
  • 编写测试代码

	
@RestController
@RequestMapping("lock")
@Log4j2
publicclassDistributedLockController{
@Autowired
privateRedisLockRegistryredisLockRegistry;

@GetMapping("/redis")
publicvoidtest1(){
Locklock=redisLockRegistry.obtain("redis");
try{
//尝试在指定时间内加锁,如果已经有其他锁锁住,获取当前线程不能加锁,则返回false,加锁失败;加锁成功则返回true
if(lock.tryLock(3,TimeUnit.SECONDS)){
log.info("lockisready");
TimeUnit.SECONDS.sleep(5);
}
}catch(InterruptedExceptione){
log.error("obtainlockerror",e);
}finally{
lock.unlock();
}
}
}
  • 测试
    启动多个实例,分别访问/lock/redis端点,一个正常秩序业务逻辑,另外一个实例访问出现如下错误c7fdd5d0-cb61-11ec-bce3-dac502259ad0.png说明第二个实例没有拿到锁,证明了分布式锁的存在。

注意,如果使用新版Springboot进行集成时需要使用Redis4版本,否则会出现下面的异常告警,主要是unlock()释放锁时使用了UNLINK命令,这个需要Redis4版本才能支持。


	
2020-05-141124,781WARNRedisLockRegistry:339-TheUNLINKcommandhasfailed(notsupportedontheRedisserver?);fallingbacktotheregularDELETEcommand
org.springframework.data.redis.RedisSystemException:Errorinexecution;nestedexceptionisio.lettuce.core.RedisCommandExecutionException:ERRunknowncommand'UNLINK'

基于Zookeeper实现

  • 引入组件

	

org.springframework.boot
spring-boot-starter-integration



org.springframework.integration
spring-integration-zookeeper
  • 在application.yml中添加zookeeper的配置

	
zookeeper:
host:172.31.0.43:2181
  • 建立配置类,注入ZookeeperLockRegistry

	
@Configuration
publicclassZookeeperLockConfiguration{
@Value("${zookeeper.host}")
privateStringzkUrl;


@Bean
publicCuratorFrameworkFactoryBeancuratorFrameworkFactoryBean(){
returnnewCuratorFrameworkFactoryBean(zkUrl);
}

@Bean
publicZookeeperLockRegistryzookeeperLockRegistry(CuratorFrameworkcuratorFramework){
returnnewZookeeperLockRegistry(curatorFramework,"/zookeeper-lock");
}
}
  • 编写测试代码

	
@RestController
@RequestMapping("lock")
@Log4j2
publicclassDistributedLockController{

@Autowired
privateZookeeperLockRegistryzookeeperLockRegistry;

@GetMapping("/zookeeper")
publicvoidtest2(){
Locklock=zookeeperLockRegistry.obtain("zookeeper");
try{
//尝试在指定时间内加锁,如果已经有其他锁锁住,获取当前线程不能加锁,则返回false,加锁失败;加锁成功则返回true
if(lock.tryLock(3,TimeUnit.SECONDS)){
log.info("lockisready");
TimeUnit.SECONDS.sleep(5);
}
}catch(InterruptedExceptione){
log.error("obtainlockerror",e);
}finally{
lock.unlock();
}
}
}
测试
启动多个实例,分别访问/lock/zookeeper端点,一个正常秩序业务逻辑,另外一个实例访问出现如下错误c81884ca-cb61-11ec-bce3-dac502259ad0.png
说明第二个实例没有拿到锁,证明了分布式锁的存在。

原文标题:这样实现分布式锁,才叫优雅!

文章出处:【微信公众号:数据分析与开发】欢迎添加关注!文章转载请注明出处。

审核编辑:汤梓红
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表德赢Vwin官网 网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉
  • 分布式
    +关注

    关注

    1

    文章

    895

    浏览量

    74498
  • spring
    +关注

    关注

    0

    文章

    340

    浏览量

    14338

原文标题:这样实现分布式锁,才叫优雅!

文章出处:【微信号:DBDevs,微信公众号:数据分析与开发】欢迎添加关注!文章转载请注明出处。

收藏 人收藏

    评论

    相关推荐

    Redis 分布式的正确实现方式

    分布式一般有三种实现方式:1. 数据库乐观;2. 基于Redis的分布式;3. 基于Zoo
    的头像 发表于 05-31 14:19 3586次阅读

    Java:Redis分布式的原理和案例

    要介绍分布式,首先要提到与分布式锁相对应的是线程、进程
    的头像 发表于 07-01 11:49 3866次阅读

    分布式的基本原理和案例实现

    前面我们有聊过乐观和悲观实现,均是对于单体架构的场景下的实现。那么现在我们来总结看下分布式情况下如何
    的头像 发表于 07-01 14:53 3327次阅读
    <b class='flag-5'>分布式</b><b class='flag-5'>锁</b>的基本原理和案例<b class='flag-5'>实现</b>

    分布式的设计与实现

    今天跟大家探讨一下分布式的设计与实现。希望对大家有帮助,如果有不正确的地方,欢迎指出,一起学习,一起进步哈。
    的头像 发表于 05-13 15:36 1748次阅读

    深入理解redis分布式

    深入理解redis分布式 哈喽,大家好,我是指北君。 本篇文件我们来介绍如何Redis实现分布式的演进过程,以及为什么不能直接用Setn
    的头像 发表于 10-08 14:13 946次阅读
    深入理解redis<b class='flag-5'>分布式</b><b class='flag-5'>锁</b>

    Redis实现分布式的几种方案

    本文将介绍什么是分布式,以及使用Redis实现分布式的几种方案。 前言 了解分布式
    的头像 发表于 10-11 15:19 676次阅读

    什么是分布式 Redis的五种分布式方案

    本地加锁的方式在分布式的场景下不适用,所以本文我们来探讨下如何引入分布式解决本地的问题。本篇所有代码和业务基于我的开源项目 PassJava。
    发表于 10-23 11:35 1172次阅读
    什么是<b class='flag-5'>分布式</b><b class='flag-5'>锁</b> Redis的五种<b class='flag-5'>分布式</b><b class='flag-5'>锁</b>方案

    tldb提供分布式使用方法

    前言:分布式分布式系统中一个极为重要的工具。目前有多种分布式的设计方案,比如借助 redis,mq,数据库,zookeeper 等第三
    的头像 发表于 11-02 14:44 888次阅读
    tldb提供<b class='flag-5'>分布式</b><b class='flag-5'>锁</b>使用方法

    spring分布式框架有哪些

    Spring分布式框架是一套基于Spring框架的解决方案,用于构建分布式系统。它提供了一系列的组件和模块,可以帮助开发人员轻松地构建可扩展、高可用、高性能的
    的头像 发表于 11-16 10:58 773次阅读

    springcloud如何实现分布式

    ,我们可以快速搭建分布式系统,并且灵活地进行伸缩和扩展。 要实现分布式系统,我们可以按照以下步骤来使用Spring Cloud: 服务注册与发现:
    的头像 发表于 11-16 11:01 679次阅读

    redis分布式如何实现

    Redis分布式是一种基于Redis实现的机制,可以用于多个进程或多台服务器之间对共享资源的并发访问控制。在分布式系统中,由于多个进程或多台服务器同时访问共享资源,可能会发生数据竞争
    的头像 发表于 11-16 11:29 523次阅读

    redis分布式死锁处理方案

    引言: 随着分布式系统的广泛应用,尤其是在大规模并发操作下,对并发控制的需求越来越高。Redis分布式作为一种常见的分布式
    的头像 发表于 11-16 11:44 1747次阅读

    redis分布式三个方法

    的三种常见的分布式实现方法:基于SETNX命令的简单分布式、基于SET命令的带过期时间的分布式
    的头像 发表于 12-04 11:22 1457次阅读

    如何实现Redis分布式

    机制,下面将详细介绍如何实现Redis分布式。 一、引言 在分布式系统中,多个节点可能同时读写同一共享资源。如果没有实现互斥访问和同步机制
    的头像 发表于 12-04 11:24 698次阅读

    分布式的三种实现方式

    分布式的三种实现方式  分布式是在分布式系统中用于实现
    的头像 发表于 12-28 10:01 894次阅读