Tomcat的Session持久化策略是什么,相信很多没有经验的人对此束手无策,为此本文总结了问题出现的原因和解决方法,通过这篇文章希望你能解决这个问题。
关于Tomcat的Session,我们都知道默认是保存在内存中。为了解决重启应用服务器Session丢失的问题,Tomcat内部的StandardManager会在正常的关闭时钝化活动的Session 并在重启的时候重新加载。
而Tomcat在StandardManager之外,还提供了对应持久化Session的Manager实现: PersistentManager,目前对应的有两种持久化的实现
FileStore
JDBCStore
分别是将活动的Session保存在磁盘上和保存到数据库中。
本次我们以FileStore为例,来分析下PersistentManager在Tomcat中的实现。
PersistentManager的配置基本上是这样的:
<Manager className="org.apache.catalina.session.PersistentManager" debug="0" saveOnRestart="true" maxActiveSessions="-1" minIdleSwap="-1" maxIdleSwap="5" maxIdleBackup="3" > <Store className="org.apache.catalina.session.FileStore" directory="/home/mytestsession"/> </Manager>
对于FileStore和JDBCStore,基本配置都类似,有差异的只是Store中对应的具体属性,比如JDBCStore需要额外指定数据的用户名和密码等。上面的配置可以直接 用于FileStore。
其中,像maxIdleBackup
、maxIdleSwap
、minIdleSwap
默认都是关闭的,默认值都是-1。当然,我们上面的配置是修改过的。默认的行为会和StandardManager一致,即在关闭重启时进行Session的钝化和解析。
而当按照我们上面的配置启动Tomcat后,服务器会根据maxIdleBackup的时间,以秒为单位,进行空闲Session的持久化。在配置的目录中,会生成以sessionId为文件名.session的文件
例如:5E62468BFF33CF7DE28464A76416B85E.session
主要参数说明:
saveOnRestart -当服务器关闭时,是否要将所有的session持久化;
maxActiveSessions - 可处于活动状态的session数;
minIdleSwap/maxIdleSwap -session处于不活动状态最短/长时间(s),sesson对象转移到File Store中;
maxIdleBackup -大于这一时间时,会将session备份。
写文件:
public void save(Session session) throws IOException { // Open an output stream to the specified pathname, if any File file = file(session.getIdInternal()); if (file == null) { return; } if (manager.getContext().getLogger().isDebugEnabled()) { manager.getContext().getLogger().debug(sm.getString(getStoreName() + ".saving", session.getIdInternal(), file.getAbsolutePath())); } try (FileOutputStream fos = new FileOutputStream(file.getAbsolutePath()); ObjectOutputStream oos = new ObjectOutputStream(new BufferedOutputStream(fos))) { ((StandardSession)session).writeObjectData(oos); } }
我们来看load操作,和StandardManager加载Session基本一致,先创建空的session,再readObjectData:
public Session load(String id) { File file = file(id); Context context = getManager().getContext(); try (FileInputStream fis = new FileInputStream(file.getAbsolutePath()); ObjectInputStream ois = getObjectInputStream(fis)) { StandardSession session = (StandardSession) manager.createEmptySession(); session.readObjectData(ois); session.setManager(manager); return session; } catch (FileNotFoundException e) { return null; } }
删除操作:
public void remove(String id) throws IOException { File file = file(id); file.delete();}
而这些load,remove等操作的触发点,就是我们之前提到过的后台线程:我们在前面分析过期的session是如何处理的时候,曾提到过,可以移步这里:对于过期的session,Tomcat做了什么?
都是使用backgroundProcess
public void backgroundProcess() { count = (count + 1) % processExpiresFrequency; if (count == 0) processExpires();}
在PersistentManager
的processExpires方法中,重点有以下几行
processPersistenceChecks(); if (getStore() instanceof StoreBase) { ((StoreBase) getStore()).processExpires(); }
其中在processPersistenceChecks
中,就会对我们上面配置的几项进行检查,判断是否要进行session文件的持久化等操作
/** * Called by the background thread after active sessions have been checked * for expiration, to allow sessions to be swapped out, backed up, etc. */public void processPersistenceChecks() { processMaxIdleSwaps(); processMaxActiveSwaps(); processMaxIdleBackups(); }
此外,通过配置pathname
为空,即可禁用session的持久化策略,在代码中,判断pathname为空时,不再创建持久化文件,从而禁用此功能。
<Manager pathname="" />
总结下,正如文档中所描述,StandardManager所支持的重启时加载已持久化的Session这一特性,相比PersistentManager只能算简单实现。要实现更健壮、更符合生产环境的重启持久化,最好使用PersistentManager并进行恰当的配置。
看完上述内容,你们掌握Tomcat的Session持久化策略是什么的方法了吗?如果还想学到更多技能或想了解更多相关内容,欢迎关注亿速云行业资讯频道,感谢各位的阅读!
免责声明:本站发布的内容(图片、视频和文字)以原创、转载和分享为主,文章观点不代表本网站立场,如果涉及侵权请联系站长邮箱:is@yisu.com进行举报,并提供相关证据,一经查实,将立刻删除涉嫌侵权内容。