如何在Spring Boot中实现分布式锁

本文涉及的产品
云数据库 Tair(兼容Redis),内存型 2GB
Redis 开源版,标准版 2GB
推荐场景:
搭建游戏排行榜
简介: 如何在Spring Boot中实现分布式锁

如何在Spring Boot中实现分布式锁

今天我们来探讨一下如何在Spring Boot中实现分布式锁。分布式锁在微服务架构中非常重要,它能够帮助我们解决在分布式环境下多个实例之间的资源竞争问题。

一、为什么需要分布式锁

在分布式系统中,多个服务实例可能会并发访问共享资源,例如数据库记录、文件等。这时,必须确保只有一个实例能够同时访问这些资源,否则可能会引发数据一致性问题或资源冲突。分布式锁就是为了解决这些问题而设计的。

二、常见的分布式锁实现方式

分布式锁的实现方式有很多,常见的包括:

  1. 基于数据库的分布式锁
  2. 基于Redis的分布式锁
  3. 基于ZooKeeper的分布式锁

本文将重点介绍如何使用Redis在Spring Boot中实现分布式锁。

三、引入依赖

首先,我们需要在Spring Boot项目中引入Redis的依赖。在pom.xml中添加如下依赖:

<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
    <groupId>org.springframework.boot</groupId>
    <artifactId>spring-boot-starter-web</artifactId>
</dependency>

四、配置Redis

接下来,我们需要在application.properties中配置Redis连接信息:

spring.redis.host=localhost
spring.redis.port=6379

五、实现分布式锁

我们可以通过Redis的SETNX命令来实现分布式锁。以下是具体的实现代码:

分布式锁工具类

package cn.juwatech.util;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Component;

import java.util.concurrent.TimeUnit;

@Component
public class RedisLock {
   

    @Autowired
    private StringRedisTemplate redisTemplate;

    public boolean tryLock(String key, String value, long timeout, TimeUnit unit) {
   
        Boolean success = redisTemplate.opsForValue().setIfAbsent(key, value, timeout, unit);
        return success != null && success;
    }

    public void unlock(String key, String value) {
   
        String currentValue = redisTemplate.opsForValue().get(key);
        if (value.equals(currentValue)) {
   
            redisTemplate.delete(key);
        }
    }
}

六、使用分布式锁

我们可以在需要使用分布式锁的业务逻辑中调用上述工具类。例如,在一个控制器中使用分布式锁来控制对共享资源的访问:

package cn.juwatech.controller;

import cn.juwatech.util.RedisLock;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import java.util.UUID;
import java.util.concurrent.TimeUnit;

@RestController
public class LockController {
   

    @Autowired
    private RedisLock redisLock;

    @GetMapping("/lock")
    public String lock(@RequestParam String key) {
   
        String value = UUID.randomUUID().toString();
        boolean success = redisLock.tryLock(key, value, 10, TimeUnit.SECONDS);

        if (success) {
   
            try {
   
                // 执行业务逻辑
                return "Lock acquired, executing business logic";
            } finally {
   
                redisLock.unlock(key, value);
            }
        } else {
   
            return "Failed to acquire lock";
        }
    }
}

七、避免死锁

在实际使用过程中,我们需要注意避免死锁。为此,分布式锁必须具有超时机制,并且在释放锁时要确保是当前持有锁的线程进行释放。上面的代码中,我们通过try-finally结构确保了业务逻辑执行完毕后能正确释放锁。

八、可重入锁

如果需要实现可重入锁,即同一个线程可以多次获取锁而不会被阻塞,可以在RedisLock中增加线程计数机制。这部分的实现较为复杂,在此不作详细展开。

总结

通过上述步骤,我们在Spring Boot项目中成功实现了基于Redis的分布式锁。分布式锁可以帮助我们解决分布式系统中的资源竞争问题,确保系统的稳定性和数据一致性。

相关实践学习
基于Redis实现在线游戏积分排行榜
本场景将介绍如何基于Redis数据库实现在线游戏中的游戏玩家积分排行榜功能。
云数据库 Redis 版使用教程
云数据库Redis版是兼容Redis协议标准的、提供持久化的内存数据库服务,基于高可靠双机热备架构及可无缝扩展的集群架构,满足高读写性能场景及容量需弹性变配的业务需求。 产品详情:https://www.aliyun.com/product/kvstore &nbsp; &nbsp; ------------------------------------------------------------------------- 阿里云数据库体验:数据库上云实战 开发者云会免费提供一台带自建MySQL的源数据库&nbsp;ECS 实例和一台目标数据库&nbsp;RDS实例。跟着指引,您可以一步步实现将ECS自建数据库迁移到目标数据库RDS。 点击下方链接,领取免费ECS&amp;RDS资源,30分钟完成数据库上云实战!https://developer.aliyun.com/adc/scenario/51eefbd1894e42f6bb9acacadd3f9121?spm=a2c6h.13788135.J_3257954370.9.4ba85f24utseFl
相关文章
|
4月前
|
缓存 NoSQL Java
SpringBoot整合Redis、以及缓存穿透、缓存雪崩、缓存击穿的理解分布式情况下如何添加分布式锁 【续篇】
这篇文章是关于如何在SpringBoot应用中整合Redis并处理分布式场景下的缓存问题,包括缓存穿透、缓存雪崩和缓存击穿。文章详细讨论了在分布式情况下如何添加分布式锁来解决缓存击穿问题,提供了加锁和解锁的实现过程,并展示了使用JMeter进行压力测试来验证锁机制有效性的方法。
SpringBoot整合Redis、以及缓存穿透、缓存雪崩、缓存击穿的理解分布式情况下如何添加分布式锁 【续篇】
|
4月前
|
资源调度 Java 调度
Spring Cloud Alibaba 集成分布式定时任务调度功能
定时任务在企业应用中至关重要,常用于异步数据处理、自动化运维等场景。在单体应用中,利用Java的`java.util.Timer`或Spring的`@Scheduled`即可轻松实现。然而,进入微服务架构后,任务可能因多节点并发执行而重复。Spring Cloud Alibaba为此发布了Scheduling模块,提供轻量级、高可用的分布式定时任务解决方案,支持防重复执行、分片运行等功能,并可通过`spring-cloud-starter-alibaba-schedulerx`快速集成。用户可选择基于阿里云SchedulerX托管服务或采用本地开源方案(如ShedLock)
131 1
|
3月前
|
消息中间件 Java 对象存储
数据一致性挑战:Spring Cloud与Netflix OSS下的分布式事务管理
数据一致性挑战:Spring Cloud与Netflix OSS下的分布式事务管理
55 2
|
4月前
|
缓存 NoSQL Java
SpringBoot整合Redis、以及缓存穿透、缓存雪崩、缓存击穿的理解、如何添加锁解决缓存击穿问题?分布式情况下如何添加分布式锁
这篇文章介绍了如何在SpringBoot项目中整合Redis,并探讨了缓存穿透、缓存雪崩和缓存击穿的问题以及解决方法。文章还提供了解决缓存击穿问题的加锁示例代码,包括存在问题和问题解决后的版本,并指出了本地锁在分布式情况下的局限性,引出了分布式锁的概念。
SpringBoot整合Redis、以及缓存穿透、缓存雪崩、缓存击穿的理解、如何添加锁解决缓存击穿问题?分布式情况下如何添加分布式锁
|
3月前
|
运维 NoSQL Java
SpringBoot接入轻量级分布式日志框架GrayLog技术分享
在当今的软件开发环境中,日志管理扮演着至关重要的角色,尤其是在微服务架构下,分布式日志的统一收集、分析和展示成为了开发者和运维人员必须面对的问题。GrayLog作为一个轻量级的分布式日志框架,以其简洁、高效和易部署的特性,逐渐受到广大开发者的青睐。本文将详细介绍如何在SpringBoot项目中接入GrayLog,以实现日志的集中管理和分析。
261 1
|
5月前
|
资源调度 Java 调度
Spring Cloud Alibaba 集成分布式定时任务调度功能
Spring Cloud Alibaba 发布了 Scheduling 任务调度模块 [#3732]提供了一套开源、轻量级、高可用的定时任务解决方案,帮助您快速开发微服务体系下的分布式定时任务。
14995 29
|
4月前
|
Java 微服务 Spring
SpringBoot+Vue+Spring Cloud Alibaba 实现大型电商系统【分布式微服务实现】
文章介绍了如何利用Spring Cloud Alibaba快速构建大型电商系统的分布式微服务,包括服务限流降级等主要功能的实现,并通过注解和配置简化了Spring Cloud应用的接入和搭建过程。
SpringBoot+Vue+Spring Cloud Alibaba 实现大型电商系统【分布式微服务实现】
|
4月前
|
Dubbo Java 调度
揭秘!Spring Cloud Alibaba的超级力量——如何轻松驾驭分布式定时任务调度?
【8月更文挑战第20天】在现代微服务架构中,Spring Cloud Alibaba通过集成分布式定时任务调度功能解决了一致性和可靠性挑战。它利用TimerX实现任务的分布式编排与调度,并通过`@SchedulerLock`确保任务不被重复执行。示例代码展示了如何配置定时任务及其分布式锁,以实现每5秒仅由一个节点执行任务,适合构建高可用的微服务系统。
72 0
|
5月前
|
消息中间件 Java 开发者
Spring Cloud微服务框架:构建高可用、分布式系统的现代架构
Spring Cloud是一个开源的微服务框架,旨在帮助开发者快速构建在分布式系统环境中运行的服务。它提供了一系列工具,用于在分布式系统中配置、服务发现、断路器、智能路由、微代理、控制总线、一次性令牌、全局锁、领导选举、分布式会话、集群状态等领域的支持。
191 5
|
5月前
|
存储 安全 Java
实现基于Spring Cloud的分布式配置管理
实现基于Spring Cloud的分布式配置管理