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
说明第二个实例没有拿到锁,证明了分布式锁的存在。

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

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

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

    关注

    1

    文章

    754

    浏览量

    74096
  • spring
    +关注

    关注

    0

    文章

    333

    浏览量

    14161

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

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

收藏 人收藏

    评论

    相关推荐

    分布式软件系统

    降到最低。负载在各处理机之间分担,可以避免临界瓶颈。 4、当现有机构中已存在几个数据库系统,而且实现全局应用的必要性增加时,就可以由这些数据库自下而上构成分布式数据库系统。 5、相等规模的分布式
    发表于 07-22 14:53

    分布式发电技术与微型电网

    几种分布式发电简介2.分布式发电与配电网互联问题3.微型电网技术4.分布式发电(电源)技术应用的障碍和瓶颈5.分布式发电(电源)技术发展方向6.结语
    发表于 03-11 13:37

    分布式整流桥测试系统的设计与实现

    分布式整流桥测试系统的设计与实现
    发表于 08-07 00:20

    分布式文件系统和fastDFS

    项目(1)(分布式文件系统、fastDFS,代码实现fastDFS 文件上传和下载)
    发表于 05-10 08:51

    在 Java 中利用 redis 实现一个分布式服务

    在 Java 中利用 redis 实现一个分布式服务
    发表于 07-05 13:14

    如何在集群部署时实现分布式session?

    集群部署时的分布式 session 如何实现
    发表于 07-17 06:57

    分布式系统的优势是什么?

    当讨论分布式系统时,我们面临许多以下这些形容词所描述的 同类型: 分布式的、删络的、并行的、并发的和分散的。分布式处理是一个相对较新的领域,所以还没有‘致的定义。与顺序计算相比、并行的、并发的和
    发表于 03-31 09:01

    HarmonyOS应用开发-分布式设计

    设计理念HarmonyOS 是面向未来全场景智慧生活方式的分布式操作系统。对消费者而言,HarmonyOS 将生活场景中的各类终端进行能力整合,形成“One Super Device”,以实现
    发表于 09-22 17:11

    鸿蒙分布式任务调度

    鸿蒙分布式任务调度,实现跨设备FA拉起
    发表于 06-12 17:28

    各种分布式电源的电气特性

    PS:渗透率的概念:从字面上理解,“渗透”就是由分布式电源发出的功率进入(渗入)到配电系统,所谓的“率”就是由分布式电源发出的电和整个系统所消耗的电(或者说总发电量)的一个比值。各种分布式电源的电气
    发表于 07-12 07:54

    如何高效完成HarmonyOS分布式应用测试?

    , getText等。② 提供远程和本地描述方式一致的分布式持测试API,仅参数不同,使用简单方便。通过UIDriver来实现。③ 分布式UI测试框架集成于IDE,开发者一键开展自动
    发表于 12-13 18:07

    分布式软总线实现近场设备间统一的分布式通信管理能力如何?

    现实中多设备间通信方式多种多样(WIFI、蓝牙等),不同的通信方式使用差异大,导致通信问题多;同时还面临设备间通信链路的融合共享和冲突无法处理等挑战。那么分布式软总线实现近场设备间统一的分布式通信管理能力如何呢?
    发表于 03-16 11:03

    spring分布式框架有哪些

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

    springclould分布式教程

    Spring Cloud是一个基于Spring Boot的分布式系统开发工具,它提供了一系列的分布式系统解决方案,可以帮助开发者快速构建和部署分布式
    的头像 发表于 11-16 10:59 226次阅读

    springcloud如何实现分布式

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