失效链接处理 |
Tomcat集群Session共享 PDF 下载
本站整理下载:
提取码:n7dp
相关截图:
主要内容:
问题由来解决方法
1. 基于Cookie+Redis+Filter解决方案实现过程优缺点踩坑
2. Tomcat内置的Session复制方案实现过程优缺点
3. 使用Session粘滞方案实现形式优缺点
4. 基于Session持久化方案
5. 基于Spring-Session无侵入性方案实现过程优缺点
踩坑结语
问题由来
当我们的业务使用单个Tomcat不足以支持访问请求的时候,需要引入Tomcat集群。而每个Tomcat的Session是不互通的,如果用户的请求落入到不同的Tomcat中,用户需要频繁的登录,给用户造成困扰。所以,在一个应用服务器产生Session之后,应该让其他应用服务器也能够获取到,也就是Session共享。
解决方法
以下几种方案有的是查资料找到的,并没有花费时间去实现,我们可以根据自己的实际情况选择使用哪一种。个人比较倾向于第1和第5种方案,因为这2种比较亲切
1. 基于Cookie+Redis+Filter解决方案
用户登录之后,将Session Id和用户信息存储到Redis中,并添加一个Cookie,将该Session Id带到客户端。当发起其他请求之后,携带该Cookie,应用服务器获取到Session Id之后去Redis中查询是否存在,如果存在则继续进行相关业务,否则提示用户未登录。那种在Cookie中存放用户信息的方式直接Pass掉了。
实现过程
登录过程
public ServerResponse<User> login(String username, String password, HttpSession session, HttpServletResponse response){
//获取数据库中的用户信息
ServerResponse<User> serverResponse = iUserService.login(username,password);
if (serverResponse.isSuccess()){
String sessionId = session.getId();
//添加Cookie
CookieUtil.writeCookie(response,sessionId);
//将sessionId和Json化的用户信息保存到分片的Redis中
RedisShardedUtil.setEx(sessionId, JsonUtil.obj2String(serverResponse.getData()), Const.RedisCache.SESSION_EXTIME);
}
return serverResponse;
}
刷新“Session”有效时间
假设“Session”的默认时间设置为半个小时,当我们登录之后,每次请求都应该将Session的有效期设置为半个小时。否则的话,一到半个小时“Session”失效了用户还得重新登录。为了解决这个问题,我们设置一个过滤器:
public class SessionExpireFilter implements Filter {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
//将ServletRequest转换为HttpServletRequest
HttpServletRequest request = (HttpServletRequest)servletRequest;
String token = CookieUtil.readCookieValue(request);
//如果token不为空的话,符合条件,则获取user信息,user不为空,则将redis缓存中的session时间重置为指定时时长
if(StringUtils.isNotBlank(token)){
String userJsonStr = RedisShardedUtil.get(token);
User user = JsonUtil.string2Obj(userJsonStr,User.class);
if(user != null){
//如果user不为空,则重置session的时间,即调用expire命令
RedisShardedUtil.expire(token, Const.RedisCache.SESSION_EXTIME);
}
}
filterChain.doFilter(servletRequest,servletResponse);
}
@Override
public void destroy() {
}
}
|