背景
负载均衡带来的问题:
当用户A在请求登录的服务时,有可能是在Tomcat1上保存的登录信息,但是当请求网站的其他服务时,有可能会是Tomcat2提供的服务,然而Tomcat2上并没有保存用户A的登录信息,所以会发出用户未登录的情况
解决:
用Redis数据库作为session服务器,用来存储用户的登录信息与sessionId,每次验证用户的登录状态时,都将请求session服务器。
1.在pom.xml文件中引入jedis依赖
<!--jedis-->
<dependency>
<groupId>redis.clients</groupId>
<artifactId>jedis</artifactId>
<version>2.6.0</version>
</dependency>
2.创建RedisPool类
package com.tiandh.common;
import com.tiandh.util.PropertiesUtil;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
/**
* @Auther: lenovo
* @Date: 2018/10/28 22:11
* @Description: Redis连接池
*/
public class RedisPool {
//jedis连接池
private static JedisPool pool;
//最大连接数
private static Integer maxTotal = Integer.parseInt(PropertiesUtil.getProperty("redis.max.total", "20"));
//在JedisPool中最大的Idle状态的(空闲的)Jedis实例的个数
private static Integer maxIdle = Integer.parseInt(PropertiesUtil.getProperty("redis.max.idle", "10"));
//在JedisPool中最小的Idle状态的(空闲的)Jedis实例的个数
private static Integer minIdle = Integer.parseInt(PropertiesUtil.getProperty("redis.min.idle", "2"));
//在borrow一个Jedis实例的时候,是否进行验证操作。
//如果赋值为true,则得到的Jedis实例肯定是可用的
private static Boolean testOnBorrow = Boolean.parseBoolean(PropertiesUtil.getProperty("redis.test.borrow", "true"));
//在return一个Jedis实例的时候,是否进行验证操作
//如果赋值为true,则放回JedisPool的Jedis实例肯定是可用的
private static Boolean testOnReturn = Boolean.parseBoolean(PropertiesUtil.getProperty("redis.test.return", "false"));
//redis.host
private static String redisHost = PropertiesUtil.getProperty("redis.host");
//redis.port
private static Integer redisPort = Integer.parseInt(PropertiesUtil.getProperty("redis.port"));
//初始化Redis连接池,该方法只会被调用一次(通过静态代码块调用)
private static void initPool(){
JedisPoolConfig config = new JedisPoolConfig();
config.setMaxTotal(maxTotal);
config.setMaxIdle(maxIdle);
config.setMinIdle(minIdle);
config.setTestOnBorrow(testOnBorrow);
config.setTestOnReturn(testOnReturn);
//当连接耗尽时,是否阻塞,true阻塞直到超时,false会抛出异常。默认为true
config.setBlockWhenExhausted(true);
//初始化JedisPool, 超时时间:1000*2 单位为毫秒
pool = new JedisPool(config, redisHost, redisPort, 1000*2);
}
//当类被加载时,调用Redis连接池初始化方法
static {
initPool();
}
//从连接池中返回一个Jedis实例
public static Jedis getJedis(){
return pool.getResource();
}
//将Jedis放回连接池中
public static void returnResource(Jedis jedis){
pool.returnResource(jedis);
}
//将损坏的连接放入BrokenResource
public static void returnBrokenResource(Jedis jedis){
pool.returnBrokenResource(jedis);
}
}
3.在 .properties文件中写好默认值
#Jedis config start
#redis主机ip地址
redis.host = 192.168.1.61
#redis服务端口
redis.port = 6379
#最大连接数
redis.max.total = 20
#最大空闲数
redis.max.idle = 10
#最小空闲数
redis.min.idle = 2
#从redis连接池获取连接时,校验并返回可用的连接
redis.test.borrow = true
#把连接放回Redis连接池时,校验并返回可用的连接
redis.test.return = false
#Jedis config end
4.Redis 连接池工具类 Jedis api封装
package com.tiandh.util;
import com.tiandh.common.RedisPool;
import lombok.extern.slf4j.Slf4j;
import redis.clients.jedis.Jedis;
/**
* @Auther: lenovo
* @Date: 2018/10/30 21:27
* @Description: Redis 连接池工具类 Jedis api封装
*/
@Slf4j
public class RedisPoolUtil {
/**
* 封装Redis set
* @param key
* @param value
* @return
*/
public static String set(String key, String value) {
Jedis jedis = null;
String result = null;
try {
jedis = RedisPool.getJedis();
result = jedis.set(key, value);
} catch (Exception e) {
log.error("set key:{} value:{} error",key,value,e);
RedisPool.returnBrokenResource(jedis);
return result;
}
RedisPool.returnResource(jedis);
return result;
}
/**
* 封装Redis API setnx
* @param key
* @param exTime 单位:秒
* @param value
* @return
*/
public static String setex(String key,int exTime, String value) {
Jedis jedis = null;
String result = null;
try {
jedis = RedisPool.getJedis();
result = jedis.setex(key, exTime, value);
} catch (Exception e) {
log.error("setex key:{} value:{} error",key,value,e);
RedisPool.returnBrokenResource(jedis);
return result;
}
RedisPool.returnResource(jedis);
return result;
}
/**
* 封装Redis API get
* @param key
* @return
*/
public static String get(String key) {
Jedis jedis = null;
String result = null;
try {
jedis = RedisPool.getJedis();
result = jedis.get(key);
} catch (Exception e) {
log.error("get key:{} error",key,e);
RedisPool.returnBrokenResource(jedis);
return result;
}
RedisPool.returnResource(jedis);
return result;
}
/**
* 封装Redis API expire
* @param key
* @param exTime 单位:秒
* @return
*/
public static Long expire(String key, int exTime) {
Jedis jedis = null;
Long result = null;
try {
jedis = RedisPool.getJedis();
result = jedis.expire(key, exTime);
} catch (Exception e) {
log.error("expire key:{} error",key,e);
RedisPool.returnBrokenResource(jedis);
return result;
}
RedisPool.returnResource(jedis);
return result;
}
/**
* 封装 Redis API del
* @param key
* @return
*/
public static Long del(String key) {
Jedis jedis = null;
Long result = null;
try {
jedis = RedisPool.getJedis();
result = jedis.del(key);
} catch (Exception e) {
log.error("del key:{} error",key,e);
}
RedisPool.returnResource(jedis);
return result;
}
}