Friday, April 28, 2017

Session Management Architecture of Play Framework

Play Framework employs an unique method of session management. It is embedding data directory into a cookie, and making clients retain it. I got used to the session management of Java Servlet, and takes the idea of saving session data to the server as granted. Therefore, Playframework's idea feels new to me.

This time, I will sort out the differences between two architectures.

Session management of Java Servlet is (maybe needless to explain) as below.

  • When HttpServletRequest#getSession is called, a session ID is generated (new session), and it is embeded in the Set-Cookie header of the response. (cookie key is typically JSESSIONID)
  • (The client sends subsequent requests with a Cookie header where session ID is embedded.)
  • When HttpSession#setAttrubute is called, data is stored in the memory associated with the session ID.
  • Client sends a session ID, and HttpServletRequest#getSession is called, then the data associated with the session ID is loaded from the memory.

In addition to this, some frameworks which uses Java Servlet automatically control the timing of generating and destroying session (often called xxx scope), and offer developers easy-to-use API.

These mechanisms are so useful, but in case of deploying several application servers, it gets a problem. As session data is stored in memory, when we deploy load balancers to the front-end and a request is balanced to the application which doesn't have the session data, the application can't get the session data. To solve this problem, most load balancers have a sticky session function, but as a system architecture it is not the greatest. It means solving application server's problems with front-end load balancers, so the interdependence between them increases. Also in terms of the availability it is not good to lose session data when an application goes down.

From another point of view, most system have persistent storage such as database in backend, so they use sessions only for taking over data in multiple requests. And just for taking over data, it only needs to embed data into cookies. However the reason this simple mechanism is not employed is that there are following two problems.

  • Session data can be tampered in the client side.
  • Data which can be embeded into cookie is limited up to 4KB.

Java Servlet solves these problems in the way which it stores only a session ID in the cookie, and stores session data in the server side. As the storage of session data is simply the memory of an application server, in case deploying multiple servers it may be common to store them in cache or storage servers. ( For example, there is a 3rd party library which store session data in memcached servers.)

On the other hand, Play Framework takes another approach to these problems. First, it signs cookie data to detect tampering. Next, it doesn't solve the maximum data size limitation of cookie. Play Framework may have a policy of that an application server should be stateless (for the sake of scaling out servers), it suggests that large session data should not be stored in application servers. Therefore we can only store these data into back-end storage or use cache feature of Play Framework. (Cache can be cooperate with memcached servers.) Cache feature of Play Framework is similar to session of Java Servlet, but then the name of "cache" suggests Play Framework prefer stateless architecture.

Making a summary, Java Servlet's "sticky session + storing session data in the server side" architecture is really strong, and scales enough. (In most cases, the influences of a server going down does not matter. However if you have fast storage such as NoSQL in the back-end, Play Framework's architecture can make the system simple. Also it fits the recently popular scale out technique, it will be the mainstream.

No comments:

Post a Comment