Redis实现分布式锁的一种实现

applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:context="http://www.springframework.org/schema/context"
       xsi:schemaLocation="
        http://www.springframework.org/schema/beans
        http://www.springframework.org/schema/beans/spring-beans.xsd
        http://www.springframework.org/schema/context
        http://www.springframework.org/schema/context/spring-context.xsd">

    <!--加载外部资源-->
    <context:property-placeholder location="classpath:jedis.properties"/>

    <context:component-scan base-package="com.xxx.jedis"/>

</beans>

jedis.properties

jedis.host = 192.168.xx.xx
jedis.port = 6379

配置类:

package com.xxx.jedis.utils;

import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

@Component
public class AppConfig implements ApplicationContextAware{
    private static ApplicationContext applicationContext;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.applicationContext = applicationContext;
    }

    public static ApplicationContext getApplicationContext() {
        return applicationContext;
    }

}

分布式锁工具类:

package com.xxx.jedis.utils;

import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import redis.clients.jedis.HostAndPort;
import redis.clients.jedis.JedisCluster;
import redis.clients.jedis.JedisPoolConfig;
import redis.clients.jedis.params.SetParams;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

@Component
public class RedisDistributeLock {
    private static final String LOCK_SUCCESS = "OK";
    private static final String RELEASE_SUCCESS = "1";
    // 可用连接实例最大数目,默认为8;如果赋值为-1,则表示不限制,如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽)
    private static final Integer MAX_TOTAL = 1024;
    // 控制一个pool最多有多少个状态为idle(空闲)的jedis实例,默认值为8
    private static final Integer MAX_IDLE = 200;
    // 集群配置,地址:端口
    private static  String nodeAddress;
    // 密码
    private static  String password;
    private static  JedisCluster jedisCluster = null;
    private static Environment env = AppConfig.getApplicationContext().getEnvironment();

    private static String getProperties(String key) {
        return env.getProperty(key);
    }

    static {
        try {
            nodeAddress = getProperties("redis.redisClusterConfig.clusters");
            password = getProperties("redis.redisClusterConfig.password");
            String[] nodeArr = nodeAddress.split(",");
            Set<HostAndPort> nodes = new HashSet<>();
            for (int i = 0; i < nodeArr.length; i++) {
                String address = nodeArr[i];
                String[] split = address.split(":");
                String host = split[0];
                int post = Integer.parseInt(split[1]);
                nodes.add(new HostAndPort(host, post));
            }
            //  创建jedis池实例
            JedisPoolConfig config = new JedisPoolConfig();
            config.setMaxTotal(MAX_TOTAL);
            config.setMaxIdle(MAX_IDLE);
            jedisCluster = new JedisCluster(nodes, 1000, 1000, 3, password, config);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 获取锁
     * @param lockKey
     * @param requestId
     * @param expireTime
     * @return
     */
    public static boolean tryLock(String lockKey, String requestId, int expireTime) {
        // 如果redis获取失败,直接返回成功,不影响业务逻辑
        if (jedisCluster == null) {
            return true;
        }
        // nx,不存在则设置成功,否则失败
        String result = jedisCluster.set(lockKey, requestId, SetParams.setParams().nx().px(expireTime));
        return  LOCK_SUCCESS.equals(result);
    }

    /**
     * 释放锁
     * @param lockKey
     * @param requestId
     * @return
     */
    public static boolean releaseLock(String lockKey, String requestId) {
        String lua_scripts = "if redis.call('get',KEYS[1]) == ARGV(1) then return redis.call('del',KEYS[1]) else return 0 end";
        Object result = jedisCluster.eval(lua_scripts, Collections.singletonList(lockKey), Collections.singletonList(requestId));
        return RELEASE_SUCCESS.equals(result);
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值