分布式锁 - adongs/security-manager-spring-boot-starter GitHub Wiki

redis实现分布式互斥锁

通过redis实现的分布式锁,效率较高,稳定性相对较弱,特别是单机

@RedisLock

参数名称 类型 说明 默认值
key string 唯一标识,支持EL表达式
timeout long 超时时间(单位毫秒) 10000
processor LockProcessor 自定义解析器 JedisLockProcessor

单机redis使用方式

1.引入redis包

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

2.配置并连接redis(在springboot中配置redis)

spring.redis.host=127.0.0.1
spring:
   redis:
      host: 127.0.0.1

3.直接在controller中使用(默认会锁定10秒钟),如果没有指定key,将自动生成key=MD5(方法名称+参数名称=JSON(参数值)),在方法执行结束,或者异常的时候将自动解锁,超时也将自动解锁

    @GetMapping(value = "a")
    @ResponseBody
    @RedisLock
    public String test(){
        return "ok";
    }

集群redis使用方式 1.引入redis包

<dependency>
	<groupId>org.redisson</groupId>
	<artifactId>redisson-spring-boot-starter</artifactId>
	<version>3.12.4</version>
</dependency>

2.配置并连接redis(在springboot中配置redis)

spring.redis.host=127.0.0.1
spring:
   redis:
      host: 127.0.0.1

3.直接在controller中使用(默认会锁定10秒钟),如果没有指定key,将自动生成key=MD5(方法名称+参数名称=JSON(参数值)),在方法执行结束,或者异常的时候将自动解锁,超时也将自动解锁

    @GetMapping(value = "a")
    @ResponseBody
    @RedisLock
    public String test(){
        return "ok";
    }

zookeeper实现分布式互斥锁

通过zookeeper实现分布式锁,效率相对redis比较低

@ZookeeperLock

参数名称 类型 说明 默认值
key string 唯一标识,支持EL表达式
processor LockProcessor 自定义解析器 ZookeeperProcessor

使用方式

1.引入zookeeper相关的包

               <dependency>
			<groupId>org.apache.zookeeper</groupId>
			<artifactId>zookeeper</artifactId>
			<version>3.4.9</version>
		</dependency>
		<dependency>
			<groupId>org.apache.curator</groupId>
			<artifactId>curator-framework</artifactId>
			<version>4.0.0</version>
		</dependency>
		<dependency>
			<groupId>org.apache.curator</groupId>
			<artifactId>curator-recipes</artifactId>
			<version>4.0.0</version>
		</dependency>

2.配置zookeeper

import org.apache.curator.RetryPolicy;
import org.apache.curator.framework.CuratorFramework;
import org.apache.curator.framework.CuratorFrameworkFactory;
import org.apache.curator.retry.ExponentialBackoffRetry;
import org.apache.zookeeper.WatchedEvent;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooKeeper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

import java.util.concurrent.CountDownLatch;

/**
 * @author yudong
 * @version 1.0
 */
@Configuration
public class ZookeeperConfig {

    private static final Logger logger = LoggerFactory.getLogger(ZookeeperConfig.class);


    @Bean
    public ZooKeeper  zooKeeper(){

        ZooKeeper zooKeeper=null;
        try {
            final CountDownLatch countDownLatch = new CountDownLatch(1);
            //连接成功后,会回调watcher监听,此连接操作是异步的,执行完new语句后,直接调用后续代码
            //  可指定多台服务地址 127.0.0.1:2181,127.0.0.1:2182,127.0.0.1:2183
            zooKeeper = new ZooKeeper("192.168.1.72:2181", 30, new Watcher() {
                @Override
                public void process(WatchedEvent event) {
                    if(Event.KeeperState.SyncConnected==event.getState()){
                        //如果收到了服务端的响应事件,连接成功
                        countDownLatch.countDown();
                    }
                }
            });
            countDownLatch.await();
            logger.info("【初始化ZooKeeper连接状态....】={}",zooKeeper.getState());

        }catch (Exception e){
            logger.error("初始化ZooKeeper连接异常....】={}",e);
        }
        return  zooKeeper;

    }

    @Bean
    public CuratorFramework curatorFramework(){
        RetryPolicy retryPolicy = new ExponentialBackoffRetry(1000, 3);
        CuratorFramework client = CuratorFrameworkFactory.newClient("192.168.1.72:2181", retryPolicy);
        client.start();
        return client;
    }
}

3.直接在controller使用

    @GetMapping(value = "a")
    @ResponseBody
    @ZookeeperLock
    public String test(){
        return "ok";
    }
⚠️ **GitHub.com Fallback** ⚠️