REST + Spring Security session problem
Thanks to that we can scale our application, add new nodes, remove nodes without care about session replication and also about consumed Java heap memory.
Recently I’ve been working on high load REST application. Actually we didn’t expect to have high traffic there but surprisingly we had much much higher that we have been prepared for (it’s so called “happy problem”). Application is based on Spring Framework and its secured with Spring Security deployed on Apache Tomcat 7. All resources are totally stateless – HttpSession is not touched by any piece of my code. Unfortunately used Java heap space was increasing all the time until:
java.lang.OutOfMemoryError: Java heap space
was thrown. In order to analyze Java heap dump and runtime usage of heap I used VisualVM.
Heap dump analysis shown that big part of memory was used by ConcurrentHashMaps used by Tomcat to store sessions. Those sessions object were almost empty but there were so many of them that they consumed ~50% of reserved Java heap space.
Add parameter to Tomcat startup script: -XX:+HeapDumpOnOutOfMemoryError
to get Java heap dump on java.lang.OutOfMemoryError: Java heap space
First thing that I’ve done was to limit session timeout from default 30 minutes to 1 minute (lowest possible option) in web.xml
:
<?xml version='1.0' encoding='UTF-8'?> <web-app xmlns='http://java.sun.com/xml/ns/javaee' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd' version='3.0'> <!-- ... --> <session-config> <session-timeout>1</session-timeout> </session-config> </web-app>
That solved the problem – heap was cleaned by GC with better results and OutOfMemoryError was not thrown anymore. But more important thing is where those sessions were coming from? The answer is: Spring Security.
By default Spring Security creates sessions if required – which means that if user has authenticated successfully then session is created. In my case it meaan – always. In order to prevent Spring Security from creating sessions create-session='never'
needs to be added to http
:
<http create-session='never'> <!-- ... --> </http>
You might think – empty session objects should not be a problem. I can tell you that for application handling few hundreds of requests per second it does a real change. Especially when its not running in the cloud or has few GB or RAM memory dedicated for Java heap. That’s how Java heap usage look like after those modifications:
Reference: Solving REST + Spring Security session problem from our JCG partner Maciej Walkowiak at the Software Development Journey blog.
I need to use session then which session shall i use ? I am using spring security session, do i need to use HttpSession ?