2024年Tomcat-session的实现:线程安全与管理(1)

@Override
public HttpSession getSession() {

if (facade == null){
if (SecurityUtil.isPackageProtectionEnabled()){
final StandardSession fsession = this;
facade = AccessController.doPrivileged(
new PrivilegedAction(){
@Override
public StandardSessionFacade run(){
return new StandardSessionFacade(fsession);
}
});
} else {
// 直接使用 StandardSessionFacade 包装即可
facade = new StandardSessionFacade(this);
}
}
return (facade);

}

再最后,要说明的是,整个sessions的管理使用一个 ConcurrentHashMap 来存放全局会话信息,sessionId->session实例。

对于同一次http请求中,该session会被存储在当前的Request栈org.apache.catalina.connector.Request#session字段中,从而无需每次深入获取。每个请求进来后,会将session保存在当前的request信息中。

3. 过期session清理?

会话不可能不过期,不过期的也不叫会话了。

会话过期的触发时机主要有三个:1. 每次进行会话调用时,会主动有效性isValid()验证,此时如果发现过期可以主动清理: 2. 后台定时任务触发清理; 3. 启动或停止应用的时候清理;(这对于非内存式的存储会更有用些)

// case1. 请求时验证,如前面所述
// org.apache.catalina.connector.Request#doGetSession
protected Session doGetSession(boolean create) {

// Return the current session if it exists and is valid
if ((session != null) && !session.isValid()) {
session = null;
}
if (session != null) {
return (session);
}

}

// case2. 后台定时任务清理
// org.apache.catalina.session.ManagerBase#backgroundProcess
@Override
public void backgroundProcess() {
// 并非每次定时任务到达时都会进行清理,而是要根据其清理频率设置来运行
// 默认是 6
count = (count + 1) % processExpiresFrequency;
if (count == 0)
processExpires();
}
/**

  • Invalidate all sessions that have expired.
    */
    public void processExpires() {

long timeNow = System.currentTimeMillis();
// 找出所有的sessions, 转化为数组遍历
Session sessions[] = findSessions();
int expireHere = 0 ;

if(log.isDebugEnabled())
log.debug("Start expire sessions " + getName() + " at " + timeNow + " sessioncount " + sessions.length);
for (int i = 0; i < sessions.length; i++) {
// 事实上后台任务也是调用 isValid() 方法 进行过期任务清理的
if (sessions[i]!=null && !sessions[i].isValid()) {
expireHere++;
}
}
long timeEnd = System.currentTimeMillis();
if(log.isDebugEnabled())
log.debug("End expire sessions " + getName() + " processingTime " + (timeEnd - timeNow) + " expired sessions: " + expireHere);
processingTime += ( timeEnd - timeNow );

}

//case3. start/stop 时触发过期清理(生命周期事件)
// org.apache.catalina.session.StandardManager#startInternal
/**

  • Start this component and implement the requirements
  • of {@link org.apache.catalina.util.LifecycleBase#startInternal()}.
  • @exception LifecycleException if this component detects a fatal error
  • that prevents this component from being used
    */
    @Override
    protected synchronized void startInternal() throws LifecycleException {

super.startInternal();

// Load unloaded sessions, if any
try {
// doLoad() 调用
load();
} catch (Throwable t) {
ExceptionUtils.handleThrowable(t);
log.error(sm.getString(“standardManager.managerLoad”), t);
}

setState(LifecycleState.STARTING);
}

/**

  • Load any currently active sessions that were previously unloaded
  • to the appropriate persistence mechanism, if any. If persistence is not
  • supported, this method returns without doing anything.
  • @exception ClassNotFoundException if a serialized class cannot be
  • found during the reload
  • @exception IOException if an input/output error occurs
    */
    protected void doLoad() throws ClassNotFoundException, IOException {
    if (log.isDebugEna
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值