首先:

我们在部署项目的时候有时候需要集群部署来保证单个平台掉线之后还可以继续给用户提供服务等,保证我们的线上业务,所以需要nginx集群去部署。这样就可以保证有一个服务器宕机之后,线上的业务也不会给我们造成损失。

我们演示的话需要三台机器是最好的,两台机器也是可以的。多起两个虚拟机而已,在每台服务器部署一个项目,然后配置到nginxl集群里面,配置好每个服务器的权重信息或者是他的匹配规则。配置好之后我们需要配置session共享,因为不同服务之间的会话是不能共享的,我们可以把会话序列化之后存储到redis中。

首先取用的系统是: windows 10,nginx尽量选择版本高一点的,低版本不支持的东西太多了。

项目采用的框架是:SpringBoot,Shiro。

了解到Shiro管理Session(会话)是在SessionManger里面,在sessionManger里面注入sessionDao,所以我们需要重写sessionDao.

话不多说,上代码:


import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.eis.AbstractSessionDAO;import java.io.Serializable;
import java.util.Collection;/*** created with IntelliJ IDEA** @author: create by limu* Date: 2020/12/14* Time:21:47*/
public class RedisSessionDao extends AbstractSessionDAO {@Overrideprotected Serializable doCreate(Session session) {return null;}@Overrideprotected Session doReadSession(Serializable sessionId) {return null;}@Overridepublic void update(Session session) throws UnknownSessionException {}@Overridepublic void delete(Session session) {}@Overridepublic Collection<Session> getActiveSessions() {return null;}
}

我们可以看到,里面重写了五个方法:doCreate(创建会话),doReadSession(读取会话),update(修改会话),delete(删除会话),getActiveSession(获取会话集合)。

其实在这里就和数据库的增删改查是一样的,每次客户端和服务端有会话操作的时候都会调用这个方法。之所以选择redis是因为redis的读写比较快一点。

全部代码如下:


import com.alibaba.fastjson.JSONObject;
import com.google.common.collect.Lists;
import com.zjxf.base.customer.SysConst;
import com.zjxf.cache.CacheKeys;
import com.zjxf.common.ShiroConst;
import com.zjxf.redis.RedisService;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.session.Session;
import org.apache.shiro.session.UnknownSessionException;
import org.apache.shiro.session.mgt.SimpleSession;
import org.apache.shiro.session.mgt.eis.AbstractSessionDAO;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.io.*;
import java.util.Collection;
import java.util.Objects;
import java.util.Optional;
import java.util.concurrent.TimeUnit;
import java.util.stream.Collectors;/*** created with IntelliJ IDEA** @author: create by limu* Date: 2020/7/20* Time:11:58*/
@Slf4j
@Service
public class RedisSessionDao extends AbstractSessionDAO {@Autowiredprivate RedisService redisService;public RedisSessionDao() {super();}public RedisSessionDao(RedisService redisService) {super();this.redisService = redisService;}@Overrideprotected Serializable doCreate(Session session) {log.debug("建立会话");Serializable sessionId = this.generateSessionId(session);this.assignSessionId(session, sessionId);JSONObject redisJson = new JSONObject();redisJson.put("session", sessionToByte(session));redisService.setContainExpire(CacheKeys.getSystemColonyRedisSession(String.valueOf(session.getId())), redisJson, ShiroConst.SHIRO_SESSION_SESSION_MAX_AGE, TimeUnit.SECONDS);return sessionId;}@Overrideprotected Session doReadSession(Serializable sessionId) {if (Objects.nonNull(sessionId)) {Optional<JSONObject> redisJsonOptional = redisService.get(CacheKeys.getSystemColonyRedisSession(String.valueOf(sessionId)));return redisJsonOptional.map(item -> byteToSession(item.getBytes("session"))).orElse(null);} else {return null;}}@Overridepublic void update(Session session) throws UnknownSessionException {if (Objects.nonNull(session) && Objects.nonNull(session.getId())) {JSONObject redisJson = new JSONObject();redisJson.put("session", sessionToByte(session));redisService.setContainExpire(CacheKeys.getSystemColonyRedisSession(String.valueOf(session.getId())), redisJson, ShiroConst.SHIRO_SESSION_SESSION_MAX_AGE, TimeUnit.SECONDS);}}@Overridepublic void delete(Session session) {log.debug("删除会话");if (Objects.nonNull(session) && Objects.nonNull(session.getId())) {redisService.delete(CacheKeys.getSystemColonyRedisSession(String.valueOf(session.getId())));}}@Overridepublic Collection<Session> getActiveSessions() {return redisService.keysValue(CacheKeys.getSystemColonyRedisSession(SysConst.EMPTY)).stream().map(item -> byteToSession(item.getBytes("session"))).collect(Collectors.toCollection(Lists::newArrayList));}/*** session序列化问题处理** @param session 会话* @return sessionToByte*/public byte[] sessionToByte(Session session) {ByteArrayOutputStream bo = new ByteArrayOutputStream();byte[] bytes = null;try {ObjectOutputStream oo = new ObjectOutputStream(bo);oo.writeObject(session);bytes = bo.toByteArray();} catch (IOException e) {e.printStackTrace();}return bytes;}/*** 字节转session** @param bytes 字节流* @return Session*/public Session byteToSession(byte[] bytes) {ByteArrayInputStream bi = new ByteArrayInputStream(bytes);ObjectInputStream in;SimpleSession session = null;try {in = new ObjectInputStream(bi);session = (SimpleSession) in.readObject();} catch (ClassNotFoundException | IOException e) {e.printStackTrace();}return session;}
}

上面我是把会话缓存到redis里面了,如果大家有出现上面序列化问题可以私信我,这样如果我们把服务重启掉的话,session在redis里面缓存的时间还没有过期的话,就算是重启服务器都是不会有掉线需要重新登录等。

Springboot如何关闭浏览器、重启服务、关机不需要重新登录会话不消失相关推荐

  1. ubuntu启动、关闭、重启服务命令

    /etc/init.d目录 init.d 目录中存放的是一系列系统服务的管理(启动与停止)脚本. 用service命令可执行init.d目录中相应服务的脚本. /etc/init.d是指向/etc/r ...

  2. ubuntu启动、关闭、重启服务service命令

    查看当前所有服务 service --status-all 结果如下: zwl@zwl-NB50TJ1-TK1:~$ service --status-all[ + ] acpid[ - ] alsa ...

  3. PowerShell2.0之桌面计算机维护(八)关闭或重启远程计算机

    在执行更名主机或添加域操作后,为了使设置生效需要重启计算机.为此需要使用Win32_OperatingSystem WMI类的shutdown()和reboot()方法,要执行的操作由向脚本传递的参数 ...

  4. Linux 关机/关闭主机/关闭系统/重启系统/注销系统的命令

    文章目录 一.shutdown 二.reboot 三.init 四.halt 五.poweroff 六.logout 七.systemctl 八.Alt + PrtSc (SysRq) + REISU ...

  5. Mac上启动、关闭、重启MySQL服务

    1. 启动服务 mysql.server start 2. 关闭服务 mysql.server stop 3. 重启服务 mysql.server restart 参考文章:LiveToolkit

  6. win10关机后自动重启_win10关机提示自动更新咋办?只需简单设置,即可彻底关闭...

    电脑是我们生活办公的一部分,win10的诞生更是让我们使用起来更加方便!但是使用win10的用户会发现这样一个问题,我们在关机时候关机栏经常会出现"更新并关机",点击后电脑还要运行 ...

  7. WIN 10 未关闭浏览器的情况下关机,再次开机Windows会自动打开浏览器并打开上次的网页修复方法

    开始-账户--登录选项-- 隐私(我的是WIN10 在最下面)-"更新或重启后,使用我的登录信息自动完成设备设置并重新打开我的应用" 关掉这个开关就OK了.

  8. Jenkins的关闭、重启

    我们用jar -jar jenkins.war来启动jenkins服务器,那么我们如何关闭或者重启jenkins服务器呢?经过搜索找到了相应的方法. 关闭jenkins服务 只需要在访问jenkins ...

  9. linux 重启命令_如何在 Ubuntu 和其他 Linux 发行版中启动、停止和重启服务 | Linux 中国...

    服务是必不可少的后台进程,它通常随系统启动,并在关机时关闭.-- Sergiu 服务是必不可少的后台进程,它通常随系统启动,并在关机时关闭.如果你是系统管理员,那么你会定期处理服务.如果你是普通桌面用 ...

最新文章

  1. 代数拓扑的数学方法正在变革脑科学
  2. pypy的安装及使用介绍
  3. 程序员需要关注的十个大数据技术
  4. ssm 返回json配置_摆脱困境:将运行时配置作为JSON返回
  5. asp.net 下载文件
  6. C++11 double转化为string
  7. Community Server Resources
  8. 基于Axis1.4的webservice接口开发(环境搭建)
  9. 人人商城APP打包教程
  10. 数据结构题集c语言版考试答案,数据结构题集(C语言版)答案.pdf
  11. 微信支付参数正确返回验签失败,建行微信服务商
  12. BF-9500警用(PDT)数字集群通信系统
  13. ubantu 防火墙
  14. 未能加载文件或程序集 或它的某一个依赖项。试图加载格式不正确的程序。问题解决
  15. 【applicationContext.xml】spring 配置文件头部声明
  16. H5移动端css实现向右横向滚动功能
  17. PC微信逆向--获取通讯录
  18. 比Postman还好用的API神器Eolink,效率担当
  19. #读写文件 EX15-17
  20. matlab优化边坡参数,基于MATLAB的土质边坡稳定可靠度计算及应用研究

热门文章

  1. Stuart Russell对话姚期智:为全人类设计AI系统,可以借鉴墨子「兼爱」思想丨2023智源大会AI安全与对齐论坛...
  2. 夜莺监控v3组件分析---Redis
  3. 为什么房地产商不能拿低价的土地把房价降下来?
  4. 最新上传缙云县五云镇欣禾社凭证(部分)
  5. yarn-cluste问题
  6. 发现了两个神奇的网站!边做试验边学编程!
  7. 浅谈梯度下降与模拟退火算法
  8. 关于GIS原理的实际分析应用题的一些解法
  9. 基于MVC的简易留言板
  10. aspx导出excel是html编码,导出Execl 系列: web页面导出到Excel乱码解决