pom依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<!-- jedis -->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.8.2</version>
</dependency>
</dependencies>
application.properties配置
#redis 配置
# Redis数据库索引(默认为0)
spring.redis.database=0
# Redis服务器地址
spring.redis.host=192.168.252.128
# Redis服务器连接端口
spring.redis.port=6379
# Redis服务器连接密码(默认为空)
spring.redis.password=123456
# 连接池最大连接数(使用负值表示没有限制)
spring.redis.jedis.pool.max-active=200
# 连接池最大阻塞等待时间(使用负值表示没有限制)
spring.redis.jedis.pool.max-wait=-1
# 连接池中的最大空闲连接
spring.redis.jedis.pool.max-idle=8
# 连接池中的最小空闲连接
spring.redis.jedis.pool.min-idle=0
# 连接超时时间(毫秒)
spring.redis.timeout=0
#spring-session 使用
spring.session.store-type=none
配置类
package com.example.demoredis.conf;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
@Configuration
public class RedisConfig {
private Logger logger = LoggerFactory.getLogger(RedisConfig.class);
@Value("${spring.redis.host}")
private String host;
@Value("${spring.redis.password}")
private String password;
@Value("${spring.redis.port}")
private int port;
@Value("${spring.redis.timeout}")
private int timeout;
@Value("${spring.redis.jedis.pool.max-active}")
private int maxActive;
@Value("${spring.redis.jedis.pool.max-idle}")
private int maxIdle;
@Value("${spring.redis.jedis.pool.min-idle}")
private int minIdle;
@Value("${spring.redis.jedis.pool.max-wait}")
private long maxWaitMillis;
@Bean
public JedisPool redisPoolFactory() {
JedisPoolConfig jedisPoolConfig = new JedisPoolConfig();
jedisPoolConfig.setMaxIdle(maxIdle);
jedisPoolConfig.setMaxWaitMillis(maxWaitMillis);
jedisPoolConfig.setMaxTotal(maxActive);
jedisPoolConfig.setMinIdle(minIdle);
JedisPool jedisPool = new JedisPool(jedisPoolConfig, host, port, timeout, password);
logger.info("JedisPool注入成功!");
logger.info("redis地址:" + host + ":" + port);
return jedisPool;
}
}
测试代码:
package com.example.demoredis;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import javax.annotation.Resource;
import java.util.Collections;
import java.util.UUID;
@RunWith(SpringRunner.class)
@SpringBootTest
public class DemoRedisApplicationTests {
@Resource
private JedisPool jedisPool;
/**
* @description 分布式锁测试
* @date 14:57 2019/9/17
**/
@Test
public void contextLoads() {
Jedis jedis = jedisPool.getResource();
String ping = jedis.ping();
System.out.println("================================jedis连接:" + ping);
/*System.out.println(lock(jedis, "a", "1", 60L));
System.out.println(jedis.get("a"));
System.out.println(unLock(jedis, "a", "2"));*/
String key = "aaa";
String value = UUID.randomUUID().toString().replaceAll("-", "");
// 锁定过期时间 s
Long lockTime = 60L;
// 尝试次数
Integer tryCount = 20;
// 每次尝试休闲时间 ms
Long trySleepTime = 1500L;
// 业务代码执行时间 s
Integer serSecond = 30;
Boolean lock = false;
try {
lock = lockRetry(jedis, key, value, lockTime, tryCount, trySleepTime);
if (lock) {
System.out.println("锁定成功-------------------------");
System.out.println("业务代码执行.......................................");
for (int i = 0; i < serSecond; i++) {
System.out.println(" ... " + (i + 1));
Thread.sleep(1000L);
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
if (lock) {
Boolean unLock = unLock(jedis, key, value);
if (unLock) {
System.out.println("解锁成功-------------------------");
} else {
System.out.println("解锁失败-------------------------");
}
}
}
System.out.println("================= 关闭连接 ==================");
jedis.close();
}
/**
* @description 重试去获取锁(锁定)
* 参数:jedis,k,v, 过期时间,重试次数,每次重试休眠时间
* @date 14:58 2019/9/17
**/
public Boolean lockRetry(Jedis jedis, String key, String value, Long timeOut, Integer retry, Long sleepTime) {
Boolean flag = false;
try {
for (int i = 0; i < retry; i++) {
flag = lock(jedis, key, value, timeOut);
System.out.println("重试" + (i + 1) + "次....... " + key + " -> " + value);
if (flag) {
System.out.println("成功获取锁--------");
break;
}
Thread.sleep(sleepTime);
}
} catch (Exception e) {
e.printStackTrace();
}
return flag;
}
/**
* @description 加锁
* 参数:jedis,k,v,过期时间
* @date 15:05 2019/9/17
**/
public Boolean lock(Jedis jedis, String key, String value, Long timeOut) {
// 保证原子性,同一时间只能一个key,并且不能被覆盖:NX:如果存在不操作(返回null), EX:超时时间单位秒
String result = jedis.set(key, value, "NX", "EX", timeOut);
// 操作成功时返回"OK"
return "OK".equals(result);
}
/**
* @description 解锁
* 参数:jedis,k,v
* @date 15:06 2019/9/17
**/
public static Boolean unLock(Jedis jedis, String key, String value) {
// 如果k,v对存在 删除,如果k,v不存在不删除,(使用脚本可以保证操作的原子性)
String luaScript = "if redis.call(\"get\",KEYS[1]) == ARGV[1] then return redis.call(\"del\",KEYS[1]) else return 0 end";
Long result = (Long) jedis.eval(luaScript, Collections.singletonList(key), Collections.singletonList(value));
return Long.valueOf(1).equals(result);
}
}