找回密码
立即注册
搜索
热搜: Java Python Linux Go
发回帖 发新帖

5475

积分

0

好友

706

主题
发表于 昨天 23:42 | 查看: 11| 回复: 0

在分布式系统中,保证数据一致性往往离不开分布式锁。云栈社区今天为大家介绍一个简单好用的分布式锁框架——Lock4j,它基于 Spring AOP 提供声明式锁,支持 Redis、Redisson、Zookeeper 等多种实现,让你告别手写加锁代码的烦恼。

Lock4j 分布式锁框架

一、简介

Lock4j是一个分布式锁组件,它提供了多种不同的支持以满足不同性能和环境的需求,基于Spring AOP的声明式和编程式分布式锁,支持RedisTemplate、Redisson、Zookeeper。

二、特性

• 简单易用,功能强大,扩展性强。
• 支持redission, redisTemplate, zookeeper,可混用,支持扩展。

开源地址:
https://gitee.com/baomidou/lock4j

三、使用前准备

3.1 引入依赖

<!-- Lock4j -->
<!-- 若使用redisTemplate作为分布式锁底层,则需要引入 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>lock4j-redis-template-spring-boot-starter</artifactId>
    <version>2.2.4</version>
</dependency>
<!-- 若使用redisson作为分布式锁底层,则需要引入 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>lock4j-redisson-spring-boot-starter</artifactId>
    <version>2.2.4</version>
</dependency>

3.2 添加redis配置

spring:
  redis:
    database: 0
    # Redis服务器地址 写你的ip
    host: 127.0.0.1
    # Redis服务器连接端口
    port: 6379
    # Redis服务器连接密码(默认为空)
    password:
    # 连接池最大连接数(使用负值表示没有限制   类似于mysql的连接池
    jedis:
      pool:
        max-active: 200
        # 连接池最大阻塞等待时间(使用负值表示没有限制) 表示连接池的链接拿完了 现在去申请需要等待的时间
        max-wait: -1
        # 连接池中的最大空闲连接
        max-idle: 10
        # 连接池中的最小空闲连接
        min-idle: 0
        # 连接超时时间(毫秒) 去链接redis服务端
        timeout: 6000

四、注解属性介绍

package com.baomidou.lock.annotation;

@Target({ElementType.METHOD})
@Retention(RetentionPolicy.RUNTIME)
@Inherited
@Documented
public @interface Lock4j {
    String name() default "";

    Class<? extends LockExecutor> executor() default LockExecutor.class;

    String[] keys() default {""};

    long expire() default -1L;

    long acquireTimeout() default -1L;

    boolean autoRelease() default true;
}

@Lock4j 注解属性说明

五、简单使用

@RestController
@RequestMapping("/mock")
public class MockController {

    @GetMapping("/lockMethod")
    @Lock4j(keys = {"#key"}, acquireTimeout = 1000, expire = 10000)
    public Result lockMethod(@RequestParam String key) {
        ThreadUtil.sleep(5000);
        return Result.OK(key);
    }
}

打开浏览器窗口,重复刷新访问:

http://localhost:8080/mock/lockMethod?key=123

成功获得锁访问结果:

{
  "success": true,
  "message": "操作成功!",
  "code": 200,
  "result": "123",
  "timestamp": 1678866083211
}

抢占不到锁,Lock4j会抛出

com.baomidou.lock.exception.LockFailureException: request failed,please retry it.

异常,通过全局异常处理返回如下结果:

{
  "success": false,
  "message": "操作失败,request failed,please retry it.",
  "code": 500,
  "result": null,
  "timestamp": 1678866034929
}

六、高级使用

6.1 自定义执行器Exector

/**
 * 自定义分布式锁执行器
 *
 * @author: austin
 * @since: 2023/3/15 15:45
 */
@Component
public class CustomRedissonLockExecutor extends AbstractLockExecutor {

    @Override
    public Object acquire(String lockKey, String lockValue, long expire, long acquireTimeout) {
        return null;
    }

    @Override
    public boolean releaseLock(String key, String value, Object lockInstance) {
        return false;
    }
}

在注解上直接指定特定的执行器:

@Lock4j(executor = CustomRedissonLockExecutor.class)

6.2 自定义分布式锁 key生成器

/**
 * 自定义分布式锁key生成器
 *
 * @author: austin
 * @since: 2023/3/15 15:46
 */
@Component
public class CustomKeyBuilder extends DefaultLockKeyBuilder {

    public CustomKeyBuilder(BeanFactory beanFactory) {
        super(beanFactory);
    }
}

6.3 自定义抢占锁失败执行策略

/**
 * 自定义抢占锁失败执行策略
 *
 * @author: austin
 * @since: 2023/3/15 15:49
 */
@Component
public class GrabLockFailureStrategy implements LockFailureStrategy {

    @Override
    public void onLockFailure(String key, Method method, Object[] arguments) {

    }
}

默认的锁获取失败策略为

com.baomidou.lock.DefaultLockFailureStrategy

6.4 手动加锁释放锁


@Service
public class LockServiceImpl implements LockService {

    @Autowired
    private LockTemplate lockTemplate;

    @Override
    public void lock(String resourceKey) {
        LockInfo lock = lockTemplate.lock(resourceKey, 10000L, 2000L, CustomRedissonLockExecutor.class);
        if (lock == null) {
            // 获取不到锁
            throw new FrameworkException("业务处理中,请稍后再试...");
        }
        // 获取锁成功,处理业务
        try {
            doBusiness();
        } catch (Exception e) {
            throw new RuntimeException(e);
        } finally {
            lockTemplate.releaseLock(lock);
        }
    }

    private void doBusiness() {
        // TODO 业务执行逻辑
    }
}



上一篇:轮子再造就为数据脱敏:Spring Boot 全局注解 + 自定义策略实战
下一篇:Quarkus vs Spring Boot:0.12秒启动,云原生Java框架性能深度测评
您需要登录后才可以回帖 登录 | 立即注册

手机版|小黑屋|网站地图|云栈社区 ( 苏ICP备2022046150号-2 )

GMT+8, 2026-6-15 18:04 , Processed in 0.780000 second(s), 41 queries , Gzip On.

Powered by Discuz! X3.5

© 2025-2026 云栈社区.

快速回复 返回顶部 返回列表