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

applicationContext.xml




    
    

    

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 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);
    }
}

你可能感兴趣的:(redis,分布式)