1、会话的问题
2、分布式会话实现思路
【1】原理分析
所有服务器的session信息都存储到了同一个Redis集群中,即所有的服务都将 Session 的信息存储到 Redis 集群中,无论是对 Session 的注销、更新都会同步到集群中,达到了 Session 共享的目的。
Cookie 保存在客户端浏览器中,而 Session 保存在服务器上。客户端浏览器访问服务器的时候,服务器把客户端信息以某种形式记录在服务器上,这就是 Session。客户端浏览器再次访问时只需要从该 Session 中查找该客户的状态就可以了。
在实际工作中我们建议使用外部的缓存设备(包括Redis)来共享 Session,避免单个服务器节点挂掉而影响服务,共享数据都会放到外部缓存容器中
【2】设计类图详解
3、RedisSessionDao
RedisSessionDao继承AbstractSessionDAO,重写了会话的创建、读取、修改等操作,全部缓存与redis中
package com.newbies.shiro.core.impl;
import com.newbies.shiro.constant.CacheConstant;
import com.newbies.shiro.utils.ShiroRedissionSerialize;
import lombok.extern.log4j.Log4j2;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.mgt.eis.AbstractSessionDAO;
import org.redisson.api.RBucket;
import org.redisson.api.RedissonClient;
import javax.annotation.Resource;
import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.concurrent.TimeUnit;
/**
* @Description 实现shiro session的memcached集中式管理~
*/
@Log4j2
public class RedisSessionDao extends AbstractSessionDAO {
@Resource(name = "redissonClientForShiro")
RedissonClient redissonClient;
private Long globalSessionTimeout;
@Override
protected Serializable doCreate(Session session) {
Serializable sessionId = generateSessionId(session);
assignSessionId(session, sessionId);
// log.info("=============创建sessionId:{}",sessionId);
RBucket<String> sessionIdRBucket = redissonClient.getBucket(CacheConstant.GROUP_CAS+sessionId.toString());
sessionIdRBucket.trySet(ShiroRedissio