目录

(1)需要导入的包

<dependency>
        <groupId>redis.clients</groupId>
        <artifactId>jedis</artifactId>
        <version>2.8.0</version>
</dependency>

(2)JedisUtil类


import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;

import java.util.Collections;

/**
 * 不采用springTemplate 的操作类
 * 因为springTemplate 的SetNx 非原子性,可能导致锁永久锁住,释放失败
 */
@Component("jedisUtil")
public class JedisUtil {

    private static final String LOCK_SUCCESS = "OK";
    private static final String SET_IF_NOT_EXIST = "NX";
    private static final String SET_WITH_EXPIRE_TIME = "PX";
    private static final Long RELEASE_SUCCESS = 1L;

    @Autowired
    private JedisPool jedisPool;

    /**
     * 尝试获取分布式锁
     * @param lockKey 锁
     * @param requestId 请求标识
     * @param expireTime 超期时间
     * @return 是否获取成功
     */
    public boolean tryGetDistributedLock(String lockKey, String requestId, int expireTime) {
        Jedis jedis = null;
        try{
            jedis = jedisPool.getResource();
            String result = jedis.set(lockKey, requestId, SET_IF_NOT_EXIST, SET_WITH_EXPIRE_TIME, expireTime);
            if (LOCK_SUCCESS.equals(result)) {
                return true;
            }
        } finally {
            //归还 jedis 连接
            if(jedis != null){
                jedis.close();
            }
        }
        return false;
    }

    /**
     * 释放分布式锁
     * @param lockKey 锁
     * @param requestId 请求标识
     * @return 是否释放成功
     */
    public boolean releaseDistributedLock(String lockKey, String requestId) {
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
            Object result = jedis.eval(script, Collections.singletonList(lockKey), Collections.singletonList(requestId));
            if (RELEASE_SUCCESS.equals(result)) {
                return true;
            }
        } finally {
            //归还 jedis 连接
            if(jedis != null){
                jedis.close();
            }
        }
        return false;
    }

    /**
     * 设置值并设置超时时间
     * @param key
     * @param value
     * @param expireTime
     * @return
     */
    public Long rpushString(String key, String value, int expireTime){
        Jedis jedis = null;
        Long result = 0L;
        try {
            jedis = jedisPool.getResource();
            result = jedis.rpush(key, value);
            if(result > 0){
                jedis.expire(key,expireTime);
            }
        } finally {
            if(jedis != null){
                jedis.close();
            }
        }
        return result;
    }

    /**
     * 批量插入
     * @param key
     * @param values
     * @param expireTime
     * @return
     */
    public Long batchRpushString(String key, String[] values, int expireTime){
        Jedis jedis = null;
        Long result = 0L;
        try {
            jedis = jedisPool.getResource();
            result = jedis.rpush(key, values);
            if(result > 0){
                jedis.expire(key,expireTime);
            }
        } finally {
            if(jedis != null){
                jedis.close();
            }
        }
        return result;

    }

    /**
     * 释放锁
     * @param lockKey
     */
    public Long releaseLock(String lockKey){
        Long result = 0L;
        Jedis jedis = null;
        try {
            jedis = jedisPool.getResource();
            result = jedis.del(lockKey);
        } finally {
            if(jedis != null){
                jedis.close();
            }
        }
        return result;
    }

}

(3)jedisPool配置

可以根据自己情况换成pringboot类配置

SRE实战 互联网时代守护先锋,助力企业售后服务体系运筹帷幄!一键直达领取阿里云限量特价优惠。
<?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">

    <bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
        <property name="maxTotal" value="3000"></property>
        <property name="maxIdle" value="300"></property>
        <property name="minIdle" value="10"></property>
        <property name="maxWaitMillis" value="15000"></property>
        <property name="minEvictableIdleTimeMillis" value="300000"></property>
        <property name="numTestsPerEvictionRun" value="3"></property>
        <property name="timeBetweenEvictionRunsMillis" value="60000"></property>
        <property name="testOnBorrow" value="true"></property>
        <property name="testOnReturn" value="true"></property>
        <property name="testWhileIdle" value="true"></property>
    </bean>

    <bean id="jedisPool" class="redis.clients.jedis.JedisPool" destroy-method="destroy">
        <!-- config -->
        <constructor-arg ref="jedisPoolConfig"/>
        <!-- host -->
        <constructor-arg value="127.0.0.1" type="java.lang.String" />
        <!-- port -->
        <constructor-arg value="6379" type="int" />
        <!-- timeout -->
        <constructor-arg value="15000" />
    </bean>
    <context:component-scan base-package="com.td.yousan.util"/>
</beans>

(4)使用举例

@Resource
private JedisUtil jedisUtil;


String lockKey=userId;//锁key
String requestId = UUID.randomUUID().toString();//请求标识
final int EXPIRED_TIME = 300*1000;//redis 数据存储过期时间

//加锁举例
boolean lockResult = jedisUtil.tryGetDistributedLock(lockKey, requestId, EXPIRED_TIME)

//放锁举例
booleanr releaseResult =jedisUtil.releaseDistributedLock(lockKey, requestId);
扫码关注我们
微信号:SRE实战
拒绝背锅 运筹帷幄