redis 分布式 session容器

分布式服务器,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();
	}
}


3.自定义的redissession容器

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 {

	}

}




  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值