集群部署的落地实现之spring shiro redis 架构 第四篇 shiro session ShiroSessionManager 优化 频繁访问redis

点点圈 提交于 2020-08-20 08:25:06

本篇文章主要解决的问题是shiro session使用redis缓存存储后,由于shiro session的设计特点,导致浏览器端请求会非常频繁访问redis,这样就造成资源的浪费,以及系统性能的下降。主要体现在来自浏览器的一个请求需要访问这个dao的update方法二十多次。这个是shiro框架本身session设计的原因造成的,每次请求过来都需要更新session内部的时间戳。这个需要对浏览器的请求做针对性的优化,也就是把session存放在request请求里面,这样访问的时候先访问request,极大减少直接访问redis次数。

import java.io.Serializable;

import javax.servlet.ServletRequest;
import javax.servlet.http.HttpServletRequest;

import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.SessionKey;
import org.apache.shiro.web.session.mgt.DefaultWebSessionManager;
import org.apache.shiro.web.session.mgt.WebSessionKey;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

 

public class ShiroSessionManager extends DefaultWebSessionManager {
    private static Logger logger = LoggerFactory.getLogger(ShiroSessionManager.class);
    /**
     * 获取session
     * 优化单次请求需要多次访问redis的问题
     * @param sessionKey
     * @return
     * @throws UnknownSessionException
     */
    @Override
    protected Session retrieveSession(SessionKey sessionKey) throws UnknownSessionException {
        Serializable sessionId = getSessionId(sessionKey);
     
        ServletRequest request = null;
        if (sessionKey instanceof WebSessionKey) {// 是web的session key 获得 request
            request = ((WebSessionKey) sessionKey).getServletRequest();
          
        }
        /*
         * request sessionId 从 request中取值 。 
         * 注意:
         * 使用HttpRequest不使用HttpSession 是因为过滤当前页面的静态文件。
         * 原因:
         * 一个URL的过滤使用redis获取获取session。
         * 当前页面是HttpRequest有效,将sessinid放入当前请求后当前URL的静态文件资源验证在HttpRequest中做过滤,不用再次访问redis。
         * 下一个URL再从redis获取获取session,验证通过委托给当前HttpRequest。
         * **/
        if (request != null && null != sessionId) {//
            
            Object sessionObj = request.getAttribute(sessionId.toString());
            if (sessionObj != null) {
                
                return (Session) sessionObj;
            }
        }
       
        
       
        //redis获取获取session
        Session session = super.retrieveSession(sessionKey);
             
        //sessionId 放入当前页面 HttpRequest 
        if (request != null && null != sessionId) {
            request.setAttribute(sessionId.toString(), session);
        }
        return session;
    }
}
 

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!