百度360必应搜狗淘宝本站头条
当前位置:网站首页 > 技术教程 > 正文

Spring Boot中的分布式锁:使用Redis和ZooKeeper实现并发控制

mhr18 2024-10-25 12:39 56 浏览 0 评论

随着应用规模的扩大和微服务架构的普及,分布式系统中对并发控制的需求也越来越迫切。在Spring Boot中,实现分布式锁是保障多个服务实例之间协同工作的关键。本文将深入介绍如何使用Redis和ZooKeeper这两种流行的分布式系统来实现高效的分布式锁。

1、为什么需要分布式锁?

在单体应用中,使用本地锁通常足以满足并发控制的需求。然而,随着服务拆分和分布式系统的兴起,多个服务实例之间的并发控制成为一个挑战。分布式锁的作用就是在分布式环境中确保对共享资源的互斥访问,防止竞争条件的发生。

2、使用Redis实现分布式锁

2.1 引入依赖

首先,需要在项目中引入Spring Data Redis的依赖:

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

2.2 创建Redis分布式锁工具类

创建一个工具类,封装了基于Redis的分布式锁的实现:

 @Component
 public class RedisLockUtil {
 
     @Autowired
     private StringRedisTemplate redisTemplate;
 
     public boolean tryLock(String key, String value, long expireTime) {
         Boolean result = redisTemplate.opsForValue().setIfAbsent(key, value, expireTime, TimeUnit.MILLISECONDS);
         return result != null && result;
    }

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

2.3 使用Redis分布式锁

在需要进行并发控制的业务方法中使用Redis分布式锁:

 @Service
 public class MyService {
 
     @Autowired
     private RedisLockUtil redisLockUtil;
 
     public void myBusinessMethod() {
         String lockKey = "myLockKey";
         String requestId = UUID.randomUUID().toString();
         long expireTime = 5000; // 锁的过期时间为5秒

        try {
            if (redisLockUtil.tryLock(lockKey, requestId, expireTime)) {
                // 获取到锁,执行业务逻辑
                // ...
            } else {
                // 未获取到锁,处理竞争失败的逻辑
                // ...
            }
        } finally {
            // 释放锁
            redisLockUtil.unlock(lockKey, requestId);
        }
    }
}

使用ZooKeeper实现分布式锁

3.1 引入依赖

引入Apache Curator Framework的依赖,它是基于ZooKeeper的分布式系统开发库:

<dependency>
    <groupId>org.apache.curator</groupId>
    <artifactId>curator-framework</artifactId>
    <version>5.1.0</version>
</dependency>

3.2 创建ZooKeeper分布式锁工具类

创建一个工具类,封装了基于ZooKeeper的分布式锁的实现:

@Component
public class ZooKeeperLockUtil {

     @Autowired
     private CuratorFramework curatorFramework;
 
     public boolean tryLock(String path, String value) {
         try {
             InterProcessMutex lock = new InterProcessMutex(curatorFramework, path);
            return lock.acquire(0, TimeUnit.MILLISECONDS);
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    public void unlock(String path) {
        try {
            InterProcessMutex lock = new InterProcessMutex(curatorFramework, path);
            lock.release();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

3.3 使用ZooKeeper分布式锁

在需要进行并发控制的业务方法中使用ZooKeeper分布式锁:

 @Service
 public class MyService {
 
     @Autowired
     private ZooKeeperLockUtil zooKeeperLockUtil;
 
     public void myBusinessMethod() {
         String lockPath = "/myLockPath";
         String requestId = UUID.randomUUID().toString();

        try {
            if (zooKeeperLockUtil.tryLock(lockPath, requestId)) {
                // 获取到锁,执行业务逻辑
                // ...
            } else {
                // 未获取到锁,处理竞争失败的逻辑
                // ...
            }
        } finally {
            // 释放锁
            zooKeeperLockUtil.unlock(lockPath);
        }
    }
}

比较与选择

4.1 Redis分布式锁的优势

  • 简单易用:使用方便,不需要额外的依赖,适合简单的并发控制场景。
  • 性能较好:Redis是内存数据库,读写速度快,适用于高并发场景。

4.2 ZooKeeper分布式锁的优势

  • 强一致性:ZooKeeper提供强一致性,确保在分布式环境中对锁的状态修改是原子操作。
  • 支持复杂场景:适用于复杂的并发控制场景,例如分布式计算、协调等。

4.3 如何选择

  • 简单场景:对于简单的并发控制需求,选择Redis分布式锁更为合适。
  • 复杂场景:对于需要强一致性和复杂并发控制的场景,选择ZooKeeper分布式锁。

总 结

本文详细介绍了在Spring Boot中使用Redis和ZooKeeper实现分布式锁的方法,并比较了它们的优劣。在实际应用中,根据项目的需求和复杂性来选择合适的分布式锁方案,以确保系统在高并发环境下的稳定运行。同时,开发人员也需要根据具体情况权衡性能和一致性的需求,以达到最佳的并发控制效果。


公众号:九极客

相关推荐

订单超时自动取消业务的 N 种实现方案,从原理到落地全解析

在分布式系统架构中,订单超时自动取消机制是保障业务一致性的关键组件。某电商平台曾因超时处理机制缺陷导致日均3000+订单库存锁定异常,直接损失超50万元/天。本文将从技术原理、实现细节、...

使用Spring Boot 3开发时,如何选择合适的分布式技术?

作为互联网大厂的后端开发人员,当你满怀期待地用上SpringBoot3,准备在项目中大显身手时,却发现一个棘手的问题摆在面前:面对众多分布式技术,究竟该如何选择,才能让SpringBoot...

数据库内存爆满怎么办?99%的程序员都踩过这个坑!

你的数据库是不是又双叒叕内存爆满了?!服务器监控一片红色警告,老板在群里@所有人,运维同事的电话打爆了手机...这种场景是不是特别熟悉?别慌!作为一个在数据库优化这条路上摸爬滚打了10年的老司机,今天...

springboot利用Redisson 实现缓存与数据库双写不一致问题

使用了Redisson来操作Redis分布式锁,主要功能是从缓存和数据库中获取商品信息,以下是针对并发时更新缓存和数据库带来不一致问题的解决方案1.基于读写锁和删除缓存策略在并发更新场景下,...

外贸独立站数据库炸了?对象缓存让你起死回生

上周黑五,一个客户眼睁睁看着服务器CPU飙到100%——每次页面加载要查87次数据库。这让我想起2024年Pantheon的测试:Redis缓存能把WooCommerce查询速度提升20倍。跨境电商最...

手把手教你在 Spring Boot3 里纯编码实现自定义分布式锁

为什么要自己实现分布式锁?你是不是早就受够了引入各种第三方依赖时的繁琐?尤其是分布式锁这块,每次集成Redisson或者Zookeeper,都得额外维护一堆配置,有时候还会因为版本兼容问题头疼半...

如何设计一个支持百万级实时数据推送的WebSocket集群架构?

面试解答:要设计一个支持百万级实时数据推送的WebSocket集群架构,需从**连接管理、负载均衡、水平扩展、容灾恢复**四个维度切入:连接层设计-**长连接优化**:采用Netty或Und...

Redis数据结构总结——面试最常问到的知识点

Redis作为主流的nosql存储,面试时经常会问到。其主要场景是用作缓存,分布式锁,分布式session,消息队列,发布订阅等等。其存储结构主要有String,List,Set,Hash,Sort...

skynet服务的缺陷 lua死循环

服务端高级架构—云风的skynet这边有一个关于云风skynet的视频推荐给大家观看点击就可以观看了!skynet是一套多人在线游戏的轻量级服务端框架,使用C+Lua开发。skynet的显著优点是,...

七年Java开发的一路辛酸史:分享面试京东、阿里、美团后的心得

前言我觉得有一个能够找一份大厂的offer的想法,这是很正常的,这并不是我们的饭后谈资而是每个技术人的追求。像阿里、腾讯、美团、字节跳动、京东等等的技术氛围与技术规范度还是要明显优于一些创业型公司...

mysql mogodb es redis数据库之间的区别

1.MySQL应用场景概念:关系型数据库,基于关系模型,使用表和行存储数据。优点:支持ACID事务,数据具有很高的一致性和完整性。缺点:垂直扩展能力有限,需要分库分表等方式扩展。对于复杂的查询和大量的...

redis,memcached,nginx网络组件

1.理解阻塞io,非阻塞io,同步io,异步io的区别2.理解BIO和AIO的区别io多路复用只负责io检测,不负责io操作阻塞io中的write,能写多少是多少,只要写成功就返回,譬如准备写500字...

SpringBoot+Vue+Redis实现验证码功能

一个小时只允许发三次验证码。一次验证码有效期二分钟。SpringBoot整合Redis...

AWS MemoryDB 可观测最佳实践

AWSMemoryDB介绍AmazonMemoryDB是一种完全托管的、内存中数据存储服务,专为需要极低延迟和高吞吐量的应用程序而设计。它与Redis和Memcached相似,但具有更...

从0构建大型AI推荐系统:实时化引擎从工具到生态的演进

在AI浪潮席卷各行各业的今天,推荐系统正从幕后走向前台,成为用户体验的核心驱动力。本文将带你深入探索一个大型AI推荐系统从零起步的全过程,揭示实时化引擎如何从单一工具演进为复杂生态的关键路径。无论你是...

取消回复欢迎 发表评论: