IDAE+SpringBoot+redis+Jedis實現分佈式鎖

①在(idea+SpringBoot+redis整合+RedisUtil可直接使用)筆記搭建成功的基礎上
②創建jedis工具類

1.集羣redis實現分佈式鎖(jedisCluster)

package com.example.redis;
import redis.clients.jedis.*;
import java.util.*;
/**
 * JedisPool工具類
 * 加載配置文件,配置連接池的參數
 * 提供獲取連接的方法
 */
public class JedisPoolUtils {
    public static JedisCluster jedisCluster;
    static {
        //獲取數據,設置到JedisPoolConfig中
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(2);
        config.setMaxIdle(1);
        Set<HostAndPort> jedisClusterNode = new HashSet<HostAndPort>();
        jedisClusterNode.add(new HostAndPort("10.160.13.114", 6381));
        jedisClusterNode.add(new HostAndPort("10.160.13.114", 6380));
        jedisClusterNode.add(new HostAndPort("10.160.13.114", 6379));
        jedisClusterNode.add(new HostAndPort("10.160.13.114", 6384));
        jedisClusterNode.add(new HostAndPort("10.160.13.114", 6383));
        jedisClusterNode.add(new HostAndPort("10.160.13.114", 6382));
        jedisCluster = new JedisCluster(jedisClusterNode, config);
    }
    /**
     * 加鎖操作
     * @param key 鎖標識
     * @param uniqueId 客戶端標識
     * @param timeOut 過期時間
     */
    public static boolean lock(String key, String uniqueId, Long timeOut) {
        boolean jedisTag = "OK".equals(jedisCluster.set(key, uniqueId, "NX", "EX", timeOut)) ? true : false;
        return jedisTag;
    }
    /**
     * 釋放鎖
     * @param key 鎖標識
     * @param uniqueId 客戶端標識
     * @return
     */
    public static boolean unLock(String key, String uniqueId) {
        //lua腳本
        String luaScript = "if redis.call(\"get\",KEYS[1]) == ARGV[1] then return redis.call(\"del\",KEYS[1]) else  return 0 end";
        boolean jedisTag = "OK".equals(jedisCluster.eval(luaScript,Collections.singletonList(key), Collections.singletonList(uniqueId)));
        return jedisTag;
    }
    /**
     * 嘗試加鎖
     * @param key 鎖標識
     * @param value 客戶端標識
     * @param timeOut 過期時間
     * @param retry 重試次數
     * @param sleepTime 重試間隔時間
     * @return
     */
    public static Boolean lockRetry(String key,String value,Long timeOut,Integer retry,Long sleepTime){
        Boolean flag = false;
        try {
            for (int i=0;i<retry;i++){
                flag = lock(key,value,timeOut);
                if(flag){
                    break;
                }
                Thread.sleep(sleepTime);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return flag;
    }
}

注意集羣有密碼時會拋出:
在這裏插入圖片描述
但是jedis又支持設置密碼,解決方法如下
http://www.mamicode.com/info-detail-1451210.html

2.單機版redis實現分佈式鎖(jedisPool)

package com.example.redis;
import redis.clients.jedis.*;
import java.util.*;

/**
 * JedisPool工具類
 * 加載配置文件,配置連接池的參數
 * 提供獲取連接的方法
 */
public class JedisPoolUtils {
    public static JedisPool jedisPool;

    static {
        //獲取數據,設置到JedisPoolConfig中
        JedisPoolConfig config = new JedisPoolConfig();
        config.setMaxTotal(2);
        config.setMaxIdle(1);
        jedisPool = new JedisPool(config, "10.160.13.114", 6381, 2000, "SSJ5IdEL");
    }
    /**
     * 加鎖操作
     * @param key 鎖標識
     * @param uniqueId 客戶端標識
     * @param timeOut 過期時間
     */
    public static boolean lock(String key, String uniqueId, Long timeOut) {
        Jedis jedis =jedisPool.getResource();
        boolean jedisTag = "OK".equals(jedis.set(key, uniqueId, "NX", "EX", timeOut)) ? true : false;
        jedis.close();
        return jedisTag;
    }

    /**
     * 釋放鎖
     * @param key 鎖標識
     * @param uniqueId 客戶端標識
     * @return
     */
    public static boolean unLock(String key, String uniqueId) {
        //lua腳本
        String luaScript = "if redis.call(\"get\",KEYS[1]) == ARGV[1] then return redis.call(\"del\",KEYS[1]) else  return 0 end";
        Jedis jedis =jedisPool.getResource();
        boolean jedisTag = "OK".equals(jedis.eval(luaScript,Collections.singletonList(key), Collections.singletonList(uniqueId)));
        jedis.close();
        return jedisTag;
    }
    /**
     * 嘗試加鎖
     * @param key 鎖標識
     * @param value 客戶端標識
     * @param timeOut 過期時間
     * @param retry 重試次數
     * @param sleepTime 重試間隔時間
     * @return
     */
    public static Boolean lockRetry(String key,String value,Long timeOut,Integer retry,Long sleepTime){
        Boolean flag = false;
        try {
            for (int i=0;i<retry;i++){
                flag = lock(key,value,timeOut);
                if(flag){
                    break;
                }
                Thread.sleep(sleepTime);
            }
        }catch (Exception e){
            e.printStackTrace();
        }
        return flag;

    }
}

另一種單機版redis分佈式鎖(https://www.cnblogs.com/liuyang0/p/6744076.html)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章