coding for world
这是最近一个问题,统计内存临时会话数和实际用户会话数,监控平台在应用以独立classloader的方式加载三方jar包,从而实现隔离业务代码完成监控告警功能。这个做法在我这菜鸡面前真的很牛。
先说结论 tomcat9直接操作session不会保活,undertow1.3.35则是只要操作session就保活
不过在区分临时会话和实际用户会话的做法很简单,定时遍历所有session,调用session.getAttribute()判断有没有保留用户信息。因为监控平台直接保留了一份session对象,直接操作session对象在tomcat下是没有问题,因为tomcat只有调用access()方法才会保活session,下面引用来自tomcat9.0embed版本源码
/**
* Update the accessed time information for this session. This method
* should be called by the context when a request comes in for a particular
* session, even if the application does not reference it.
*/
@Override
public void access() {
this.thisAccessedTime = System.currentTimeMillis();
if (ACTIVITY_CHECK) {
accessCount.incrementAndGet();
}
}
这三tomcat中的getAttribute方法,没有任何保活逻辑
/**
* Return the object bound with the specified name in this session, or
* <code>null</code> if no object is bound with that name.
*
* @param name Name of the attribute to be returned
*
* @exception IllegalStateException if this method is called on an
* invalidated session
*/
@Override
public Object getAttribute(String name) {
if (!isValidInternal()) {
throw new IllegalStateException
(sm.getString("standardSession.getAttribute.ise"));
}
if (name == null) {
return null;
}
return attributes.get(name);
}
tomcat是只有请求来了,容器调用access方法进行保活。内置清理任务,根据存活时间清理
下面是undertow的保活,在getAttribute里也会调用bumpTimeout来保活,看了源码1.3.35的,SessionImpl的任何session操作都会保活,每一个session都有自己定时器,到点清理
@Override
public Object getAttribute(final String name) {
if (invalid) {
throw UndertowMessages.MESSAGES.sessionNotFound(sessionId);
}
bumpTimeout();
return attributes.get(name);
}
奇妙的机制,差点搞到内存泄漏,哈哈哈哈,刚刚看了一眼undertow2.6版本 直接操作session已经不得保活了,懒得细看了。没想到session这部分代码 tomcat9和undertow1.3.35的居然给我看完了,感觉这部分的源码也没那么复杂哈。
自己记录 不慎有讲错的地方 麻烦指出 共同学习