分布式服务器,redis作为session共享的容器
1.redis的连接信息
redisip=xxx.xxx.xxx.xxx
redisport=6379
redispw=xxxxxxxxxxx
redismaxIdle=100
redisminIdle=10
redismaxTotal=200
2.作为redis连接池,要引入额外的两个包
package com.easier.DB;
import java.io.IOException;
import java.util.Properties;
import org.apache.log4j.LogManager;
import org.apache.log4j.Logger;
import redis.clients.jedis.Jedis;
import redis.clients.jedis.JedisPool;
import redis.clients.jedis.JedisPoolConfig;
public class RedisPools {
private static JedisPool jedisPool = null;
static {
Logger log = LogManager.getLogger(RedisPools.class);
Properties properties = new Properties();
try {
properties.load(Thread.currentThread().getContextClassLoader()
.getResourceAsStream("jdbc.properties"));
} catch (IOException e) {
e.printStackTrace();
}
JedisPoolConfig config = new JedisPoolConfig();
// 连接耗尽时是否阻塞, false报异常,ture阻塞直到超时, 默认true
config.setBlockWhenExhausted(true);
// 设置的逐出策略类名, 默认DefaultEvictionPolicy(当连接超过最大空闲时间,或连接数超过最大空闲连接数)
config.setEvictionPolicyClassName("org.apache.commons.pool2.impl.DefaultEvictionPolicy");
// 是否启用pool的jmx管理功能, 默认true
config.setJmxEnabled(true);
// MBean ObjectName = new
// ObjectName("org.apache.commons.pool2:type=GenericObjectPool,name=" +
// "pool" + i); 默 认为"pool", JMX不熟,具体不知道是干啥的...默认就好.
config.setJmxNamePrefix("pool");
// 是否启用后进先出, 默认true
config.setLifo(true);
// 最大空闲连接数, 默认8个
config.setMaxIdle(Integer.parseInt(properties
.getProperty("redismaxIdle")));
// 最大连接数, 默认8个
config.setMaxTotal(Integer.parseInt(properties
.getProperty("redismaxTotal")));
// 获取连接时的最大等待毫秒数(如果设置为阻塞时BlockWhenExhausted),如果超时就抛异常, 小于零:阻塞不确定的时间,
// 默认-1
config.setMaxWaitMillis(-1);
// 逐出连接的最小空闲时间 默认1800000毫秒(30分钟)
config.setMinEvictableIdleTimeMillis(1800000);
// 最小空闲连接数, 默认0
config.setMinIdle(Integer.parseInt(properties
.getProperty("redisminIdle")));
// 每次逐出检查时 逐出的最大数目 如果为负数就是 : 1/abs(n), 默认3
config.setNumTestsPerEvictionRun(3);
// 对象空闲多久后逐出, 当空闲时间>该值 且 空闲连接>最大空闲数
// 时直接逐出,不再根据MinEvictableIdleTimeMillis判断 (默认逐出策略)
config.setSoftMinEvictableIdleTimeMillis(1800000);
// 在获取连接的时候检查有效性, 默认false
config.setTestOnBorrow(false);
// 在空闲时检查有效性, 默认false
config.setTestWhileIdle(false);
// 逐出扫描的时间间隔(毫秒) 如果为负数,则不运行逐出线程, 默认-1
config.setTimeBetweenEvictionRunsMillis(-1);
String host = properties.getProperty("redisip");
int port = Integer.parseInt(properties.getProperty("redisport"));
String password = properties.getProperty("redispw");
jedisPool = new JedisPool(config, host, port, 3000, password);
log.info("redis线程池创建成功!host:"+host+",port:"+port);
}
public static Jedis getJedis() {
return jedisPool.getResource();
}
public static void close(Jedis jedis) {
if (jedis != null)
jedis.close();
}
}
package com.easier.support;
import java.util.HashMap;
import java.util.Map;
import com.alibaba.fastjson.JSONObject;
public class RedisSession {
private String id;
private Map<String, String> map;
private long creationTime;//创建时间
private long lastAccessedTime;//上一次登录时间
private int maxInactiveInterval=3600;//最大失效时间,单位(秒)
public boolean invalidate()
{
return System.currentTimeMillis()<lastAccessedTime+(maxInactiveInterval*1000)?true:false;
}
public String getAttribute(String name) {
return map.get(name);
}
public void setAttribute(String name, String value) {
if(map==null)
{
map = new HashMap<String, String>();
}
map.put(name, value);
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public long getCreationTime() {
return creationTime;
}
public void setCreationTime(long creationTime) {
this.creationTime = creationTime;
}
public long getLastAccessedTime() {
return lastAccessedTime;
}
public void setLastAccessedTime(long lastAccessedTime) {
this.lastAccessedTime = lastAccessedTime;
}
public int getMaxInactiveInterval() {
return maxInactiveInterval;
}
public void setMaxInactiveInterval(int maxInactiveInterval) {
this.maxInactiveInterval = maxInactiveInterval;
}
public Map<String, String> getMap() {
return map;
}
public void setMap(Map<String, String> map) {
this.map = map;
}
@Override
public String toString() {
return "RedisSession [id=" + id + ", map=" + map + ", creationTime="
+ creationTime + ", lastAccessedTime=" + lastAccessedTime
+ ", maxInactiveInterval=" + maxInactiveInterval + "]";
}
/*public static void main(String[] args) {
RedisSession redisSession = new RedisSession();
redisSession.setAttribute("user", "kiddie");
redisSession.setCreationTime(System.currentTimeMillis());
redisSession.setId("redisid255");
redisSession.setLastAccessedTime(System.currentTimeMillis());
redisSession.setMaxInactiveInterval(3600);
String result = JSONObject.toJSONString(redisSession);
System.out.println(result);
RedisSession rs = JSONObject.parseObject(result, RedisSession.class);
System.out.println(rs);
}*/
}
4.redisSesionUtils,用于各种redissession的操作
package com.easier.utils;
import redis.clients.jedis.Jedis;
import com.alibaba.fastjson.JSONObject;
import com.easier.DB.RedisPools;
import com.easier.support.RedisSession;
public class RedisSessionUtils {
public static RedisSession getRedisSession(String id) {
RedisSession redisSession = null;
Jedis jedis = RedisPools.getJedis();
if (jedis.exists(id)) {
String jsonResult = jedis.get(id);
redisSession = JSONObject.parseObject(jsonResult,
RedisSession.class);
}
RedisPools.close(jedis);
return redisSession;
}
public static RedisSession addOrUpdateRedisSession(RedisSession redisSession) {
Jedis jedis = RedisPools.getJedis();
String result = JSONObject.toJSONString(redisSession);
jedis.setex(redisSession.getId(),
redisSession.getMaxInactiveInterval(),result);
RedisPools.close(jedis);
return redisSession;
}
private static String createRedisSessionID() {
return MD5Utils.toMD5(System.currentTimeMillis() + "");
}
public static RedisSession createRedisSession() {
RedisSession redisSession = new RedisSession();
redisSession.setId(createRedisSessionID());
redisSession.setCreationTime(System.currentTimeMillis());
redisSession.setLastAccessedTime(System.currentTimeMillis());
redisSession.setMaxInactiveInterval(Integer.parseInt(PropertiesUtils
.get("sessiontime")));
return redisSession;
}
public static void main(String[] args) {
String id = "foo";
Jedis jedis = RedisPools.getJedis();
System.out.println(jedis.exists(id));
}
}package com.easier.utils;
import redis.clients.jedis.Jedis;
import com.alibaba.fastjson.JSONObject;
import com.easier.DB.RedisPools;
import com.easier.support.RedisSession;
public class RedisSessionUtils {
<span style="white-space:pre"> </span>public static RedisSession getRedisSession(String id) {
<span style="white-space:pre"> </span>RedisSession redisSession = null;
<span style="white-space:pre"> </span>Jedis jedis = RedisPools.getJedis();//从线程池得到redis连接
<span style="white-space:pre"> </span>if (jedis.exists(id)) {//如果key存在
<span style="white-space:pre"> </span>String jsonResult = jedis.get(id);//得到key的json的value
<span style="white-space:pre"> </span>redisSession = JSONObject.parseObject(jsonResult,
<span style="white-space:pre"> </span>RedisSession.class);//将得到的json格式数据变成redisSession对象
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>RedisPools.close(jedis);//关闭连接
<span style="white-space:pre"> </span>return redisSession;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>public static RedisSession addOrUpdateRedisSession(RedisSession redisSession) {
<span style="white-space:pre"> </span>Jedis jedis = RedisPools.getJedis();//从线程池得到redis连接
<span style="white-space:pre"> </span>String result = JSONObject.toJSONString(redisSession);
<span style="white-space:pre"> </span>jedis.setex(redisSession.getId(),
<span style="white-space:pre"> </span>redisSession.getMaxInactiveInterval(),result);
<span style="white-space:pre"> </span>RedisPools.close(jedis);
<span style="white-space:pre"> </span>return redisSession;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>private static String createRedisSessionID() {
<span style="white-space:pre"> </span>return MD5Utils.toMD5(System.currentTimeMillis() + "");
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>public static RedisSession createRedisSession() {
<span style="white-space:pre"> </span>RedisSession redisSession = new RedisSession();
<span style="white-space:pre"> </span>redisSession.setId(createRedisSessionID());//得到随机的sessionid
<span style="white-space:pre"> </span>redisSession.setCreationTime(System.currentTimeMillis());//创建时间
<span style="white-space:pre"> </span>redisSession.setLastAccessedTime(System.currentTimeMillis());//上次进入时间
<span style="white-space:pre"> </span>redisSession.setMaxInactiveInterval(Integer.parseInt(PropertiesUtils
<span style="white-space:pre"> </span>.get("sessiontime")));//session失效时间
<span style="white-space:pre"> </span>return redisSession;
<span style="white-space:pre"> </span>}
<span style="white-space:pre"> </span>
<span style="white-space:pre"> </span>public static void main(String[] args) {
<span style="white-space:pre"> </span>String id = "foo";
<span style="white-space:pre"> </span>Jedis jedis = RedisPools.getJedis();
<span style="white-space:pre"> </span>System.out.println(jedis.exists(id));
<span style="white-space:pre"> </span>}
}
5.redissession过滤器,这一段很重要
package com.easier.filter;
import java.io.IOException;
import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import com.easier.support.RedisSession;
import com.easier.utils.PropertiesUtils;
import com.easier.utils.RedisSessionUtils;
public class RedisSessionFilter implements Filter {
private static String redisSessionKey = "REDISSESSIONID";//用于cookies的key
@Override
public void doFilter(ServletRequest request, ServletResponse response,
FilterChain chain) throws IOException, ServletException {
HttpServletRequest httpServletRequest = (HttpServletRequest) request;
HttpServletResponse httpServletResponse = (HttpServletResponse) response;
String redisSessionId = null;
Cookie[] cookies = httpServletRequest.getCookies();
if (cookies != null) {//cookies有可能没有带cookies过来,防止空指针报错
for (Cookie cookie : cookies) {
if (redisSessionKey.equalsIgnoreCase(cookie.getName())) {
redisSessionId = cookie.getValue();//根据客户端传过来的key值得到id值
break;
}
}
}
if (redisSessionId != null) {//如果redisSessionId不为空,则可以从redis数据库拿到session
RedisSession redisSession = RedisSessionUtils
.getRedisSession(redisSessionId);
if (redisSession != null) {//如果不为空,就把session存入request以便Controller调用
httpServletRequest.setAttribute(PropertiesUtils.get("session"),
redisSession);
}
}
chain.doFilter(httpServletRequest, httpServletResponse);//过滤器放行
RedisSession redisSession = (RedisSession) httpServletRequest
.getAttribute(PropertiesUtils.get("session"));//从request中得到redisSession
if (redisSession != null) {//如果不为空,则向客户端写入cookies并且更新过期的时间
redisSession.setLastAccessedTime(System.currentTimeMillis());//更新最后操作时间
RedisSessionUtils.addOrUpdateRedisSession(redisSession);
Cookie cookie = new Cookie(redisSessionKey, redisSession.getId());
cookie.setMaxAge(redisSession.getMaxInactiveInterval());//设置过期时间
httpServletResponse.addCookie(cookie);
}
}
@Override
public void destroy() {
}
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
}