How would you do session management for a website develloped in angular that consumes two types of REST services. The first is developped in ruby and the other is developped in Java Spring. For now I manage it with a shared table in a mysql database and a session id but i don't think this is the best solution.
A example of this problem is: how does the tomcat server knows about the session used by the rails application?
Thank you,
Davy
The REST servers should not do any session management.
they only get requests and responds to them. The client–server communication is constrained by no client context being stored on the server between requests.
How you are doing your session management in your application should not be affected by what resource provider you are using.
I agree with Philipp that a REST service should be as stateless as possible however I need some state in my appliation. (authentication)
I have found an article that gives the solution for my problem in this post about
session stickiness. This comes close to my situation of application servers on different machines and with different technologies.
In short they give 3 solutions:
maintain a session through cookies en session ids
use a database or cache
don't use a round robin technique but always let the load balancer send your request to the machine that stores your session. (not when you use diffent technologies)I.
Related
Which are the advantages of the Spring Session compared with Servlet HttpSession?
Where should I use the Spring session?
Spring Session do more advanced things than Tomcat HttpSession. HttpSession it's used in Servlets and Spring Session can be used in Servlets, RestApi...
Ex:
Why Spring Session and HttpSession
HttpSession actually is limited to a certain web container, which means its lifecycles are maintained by a container like Tomcat/Jetty. But when you have a couple of servers (normally a reverse agency like Nginx + several server instances), each server would have its own session, so a user will have to login more than once when successive requests hit different servers (e.g. Server A for the 1st time and server B for the 2nd time).
Keys to address this problem include:
1.Sync session informations among all server instances or
2.Maintain a global session
Actually Spring session aims at the 2nd solution, providing a global session management framework while supporting extensions with different 3rd-party persistence libraries like Redis/JDBC/In Memory.
Theoretically syncing sessions by yourself is also ok, but hard to maintain and time-consuming.
HttpSession
Provides a way to identify a user across more than one page request or visit to a Web site and to store information about that user. The servlet container uses this interface to create a session between
an HTTP client and an HTTP server. The session persists for a
specified time period, across more than one connection or page request
from the user. A session usually corresponds to one user, who may
visit a site many times. The server can maintain a session in many
ways such as using cookies or rewriting URLs.
More Info
Spring Session
Spring Session provides a transparent approach to resolving the
limitations of the HTTP session. It provides central session
management without being tied to container-specific solutions (e.g
Tomcat, Jetty etc.)...
Traditionally HTTPSession is container-specific i.e the container will
create a session and provide the session ID to the application. This
essentially means that if our application is running on a clustering
environment, each container will have its own HTTPSession management.
Session information is not shared across the different servers. The
session-id generated by application server 1 will be unknown to the
second application server.
More Info
Spring Session provides transparent integration with HttpSession. This
means that developers can switch the HttpSession implementation out
with an implementation that is backed by Spring Session.
More Info
Folks.
I am using spring boot framework with tomcat containers, and because of several reasons for maintaining this service, I try to share sessions with Redis. Usually, I used spring-session-data-redis which is recommended by following the guide.
https://www.baeldung.com/spring-session
but, I have a question about session-sharing with Redis by using spring-session-data-redis. If I need to set and use multiple server clusters to reduce traffic stress (with load balancer), should I set also a Tomcat configuration to use Redis session? or is spring-session-data-redis enough to session-sharing for multiple server clusters?
if someone visited the wrong sub-path in the specific domain (for example somewheredomain.com/not_spring_project/some_path), I guess the spring session is not working to share session. if this guy visited A-tomcat server with the correct path and went to another tomcat server with the wrong-path, maybe another tomcat server which the someone visited the first time can generate(or re-write) jsessionid.
is there anyone able to explain the best usuage session sharing for spring boot with an external tomcat container?
A while i struggled to find the answer of this question. after making test-bed with multiple VMs on google cloud platform, finally I got the answer.
The answer is very simple, the session key of Spring-session is not jsession_id :P
so, developers don't need to worry The multiple tomcat servers issues new jsession_id.
just developers need to use spring-session-data with redis, then they can share session data on redis server.
I would like to know if Servlet specifications provides a way to load http sessions into my web application.
The idea is simple : every time a new http client is connected, a new session is created... and I will send this session and its values into a database (for the time being this step is easy to do).
If this "master server" dies, another machine will take its IP address, so http clients will now send their requests to this new machine (lets call it "slave server").
Here I would like my slave server retrieve sessions from the old server... but I don't know which method from Servlet specifications can "add" session ! Is there a way to do it ?
PS: it's for an university project, so I cannot use already existing modules like Tomcat's mod_jk for this homemade load-balancer.
EDIT:
I think that a lot of people think I am crazy to not use already existing tools. It's an university project, and I have to make it with my bare hands in order to show to my professors the low level mecanisms that I have used. I already know it would be crazy to use what I am doing in production, when this project will be finished, it will be thrown in the trash.
For the moment, I didn't find a "standard way" to make it with the Servlet specifications, but I can maybe do it with Manager and Session from Tomcat native classes... How can I get the instances for those interfaces ?
This isn't exactly a new idea and is called session replication. There are a couple of ways to do this. The easiest ones imho are (in ascending order of preference):
Jetty's Session clustering with a database
Tomcat's Session clustering. I personally prefer the BackupManager, which makes sure that a session lives on 2 servers in a cluster at any given point in time and forwards clients accordingly. This reduces the network traffic for session replication to a bare minimum.
Session replication with a distributed cache like hazelnuts or ehcache. There are plugins for both jetty and Tomcat to do this. Since most often a cache is used anyway, this is to be the best solution for me. What I tend to do is to put 2 round robin balanced varnish servers in front of such a cluster, which serve the dual purpose role of load balancing the cluster and serving static content from in memory cache.
As for your university project, I'd turn in an embedded jetty with automatic session replication which connects to other servers via broadcast using hazelcast. Useful, not overcomplicated (iirc, you need to implement 2 relatively simple interfaces), yet powerful. Put a varnish in front of your test machines and you should be good to go.
This feature is supported by all major Java EE application server vendors out of the box, so you shouldn't implement anything by yourself. As Markus wrote it is referred as session replication or session persistence. You can take a look at WebSphere Liberty which is available for free for development. It supports it out of the box, without need to implement anything. You just need to:
install Liberty Download just the Liberty profile runtime
configure session replication Configuring session persistence for the Liberty profile
install and configure IBM Http Server for load balancing Configuring a web server plug-in for the Liberty profile
Suppose I have more than one web application servers running and I am logging in a User from Server1 thus his session starts.As http is stateless, suppose if the next request goes to Server3 than the Sever1 which was used to login to the application,if I use cookies, hidden form , its not going to work in Server2.
So how do I manage the session ?, maybe by generating an ID (or even reusing the jsessioid generated ) and storing it in a central database,so that all servers can access this session ID and validate it before processing the request.Then in that case, I need to develop a mechanism to store all the session data as object to the database.
Is there any other built in mechanisms available ?
If you are deploying application on more than one server, you should use "Clustering". Application servers are able to handle this scenario using "session replication". With session replication, each server will have a copy of the active users session. IF the first request goes to server A and second request goes to server B, it will be transparent to application code and end user.
For clustering/session replication in Tomcat, you can have a look at this link.
Spring provides the session management:
Spring Session makes it trivial to support clustered sessions without being tied to an application container specific solution. It also provides transparent integration with:
HttpSession - allows replacing the HttpSession in an application container (i.e. Tomcat) neutral way, with support for providing session IDs in headers to work with RESTful APIs
WebSocket - provides the ability to keep the HttpSession alive when receiving WebSocket messages
WebSession - allows replacing the Spring WebFlux’s WebSession in an application container neutral way
Source: Spring docs.
Please check this for further information: https://spring.io/projects/spring-session#overview
If your infrastructure ( Server 1, 2...) are connected to a single network appliance like Citrix Netscalar, then you can use IP or Cookie Persistence so that netscalar sends further requests to the same server.
Please suggest what are different ways of achieving load balance on database while more than one tomcat is accessing the same database?
Thanks.
This is a detailed example of using multiple tomcat instances and an apache based loadbalancing control
Note, if you have a hardware that would make a load balancing, its even more preferable way as to me (place it instead of apache).
In short it works like this:
A request comes from some client to apache web server/hardware loadbalancer
the web server determines to which node it wants to redirect the request for futher process
the web server calls Tomcat and tomcat gets the request
the Tomcat process the request and sends it back.
Regarding the database :
- tomcat itself has nothing to do with your Database, its your application that talks to DB, not a Tomcat.
Regardless your application layer you can establish a cluster of database servers (For example google for Oracle RAC, but its entirely different story)
In general, when implementing application layer loadbalancing please notice that the common state of the application gets replicated.
The technique called "sticky session" partially handles the issue but in general you should be aware of it.
Hope this helps