Hi, On some applications we have: - quite low number of users most of the time - high number of users twice a year
These applications store quite a lot of information in session. To cope with the surge of users, we would need to: - either increase mx (Java max memory) - or use short session timeout (lifetime) - or use horizontal scaling (k8s... but we currently have no such solutions) The best solution for us would be a "maxActiveSessions" setting which would set a high bound to the number of sessions, but compared to current implementation, it would allow new sessions and expire old sessions. We mostly achieved this with a cron (1) calling a script (2): it uses tomcat-manager to force a shorter lifetime when there is a lot of sessions. Since it would be nicer to have this behavior directly in tomcat, I did it using a small class extending StandardManager (2). I wonder if this could be useful to other users?... cu. (1) */10 * * * * ~/tomcat/expire-if-too-many-sessions student-info 4000 8 (2) script "expire-if-too-many-sessions": -------------- webapp=$1 max_sessions=$2 idle=$3 nb_sessions=`curl -s --user "$user" "$url/manager/text/list" | grep "$webapp" | awk -F: '{print $3}'` if [ $nb_sessions -gt $max_sessions ]; then echo "too many sessions ($nb_sessions > $max_sessions). telling tomcat to expire $webapp sessions inactive more than $idle" out=`curl -s --user "$user" "$url/manager/text/expire?path=/$webapp&idle=$idle"` if echo $out | grep -q '^OK'; then : else echo "error expiring: $out" fi fi ------------- (3) ------------- protected int maxActiveSessionsGoal = -1; /** * If you have too many sessions, you may memory overflow. * This setting will expire old sessions to keep sessions memory usage low. * -1 is no limit */ public void setMaxActiveSessionsGoal(int max) { maxActiveSessionsGoal = max; } public void processExpires() { super.processExpires(); if (maxActiveSessionsGoal >= 0) { var nb = getActiveSessions(); if (nb > maxActiveSessionsGoal) { expireNbOldSessions(nb - maxActiveSessionsGoal); } } } private void expireNbOldSessions(int nbToRemove) { var time = sessions.values().stream() .mapToLong(Session::getLastAccessedTimeInternal).sorted() // we want the nbToRemove-th element in the array .skip(nbToRemove).findFirst() .orElse(0); if (time == 0) { log.error("internal error expireNbOldSessions"); return; } log.info("To achieve maxActiveSessionsGoal (" + maxActiveSessionsGoal + ") for " + getContext().getBaseName() + ", we will expire sessions older than " + new Date(time) + " (" + nbToRemove + " sessions)"); for (Session session : findSessions()) { if (session.getLastAccessedTimeInternal() < time) { session.expire(); } } } ------------- --------------------------------------------------------------------- To unsubscribe, e-mail: users-unsubscr...@tomcat.apache.org For additional commands, e-mail: users-h...@tomcat.apache.org