sessionStatMap is full

sessionStatMap is full

背景

线上的程序,突然报了sessionStatMap is full的error,程序的连接池用的是druid,版本号1.1.11,老大问这是什么错,赶紧修复下。。。。

排查过程

首先去github上的druid中搜索这个错误,发现有如下几个issues:

点进去看了下,也没说到底要不要紧,然后去google上搜了下,也基本没说怎么解决,或者不解决到底影不影响系统运行

没办法,只能去看源码

public WebSessionStat getSessionStat(String sessionId, boolean create) {
sessionStatLock.readLock().lock();
try {
WebSessionStat uriStat = sessionStatMap.get(sessionId);

if (uriStat != null) {
return uriStat;
}
} finally {
sessionStatLock.readLock().unlock();
}

if (!create) {
return null;
}

sessionStatLock.writeLock().lock();
try {
WebSessionStat uriStat = sessionStatMap.get(sessionId);

if (uriStat == null) {
if (sessionStatMap.size() >= this.getMaxStatSessionCount()) {
long fullCount = uriSessionMapFullCount.getAndIncrement();

if (fullCount == 0) {
LOG.error("sessionStatMap is full");
}
}

WebSessionStat newStat = new WebSessionStat(sessionId);

sessionStatMap.put(sessionId, newStat);

return newStat;
}

return uriStat;
} finally {
sessionStatLock.writeLock().unlock();
}
}

可以看到是sessionStatMap的size超过了最大值(1000),然后抛了这个错误,按照常理说,如果大于1000了,应该就不再生成新的WebSessionStat,放到map中了,不然肯定造成map无限大啊

但是看了druid的监控界面,发现监控的session稳定在了1000,没有无限增长,难道map会删除?

看到sessionStatMap的类型是LRUCache,该类重写了removeEldestEntry方法,继续跟踪,在map的afterNodeInsertion中调用了removeEldestEntry(删除元素),然后在putVal中的最后调用了afterNodeInsertion,这时疑惑就解开了,继续put的时候会在添加完后删除第一个元素,所以map一直维持在1000的大小

总结

这个sessionStatMap is full的error就是相当于个提示信息,告诉你监控的session个数达到了1000了,后续不会增长了(加入新的删除老的),其实打个warn就行了,打成error,我们时不时就接到这个报警

原文地址:https://www.cnblogs.com/muzhao/p/11353983.html