When running multiple instances behind a load balancer, maintaining sessions can be a problem. For example, let’s say instance-2 receives a login request and establishes a session for the user. However, the second request may not go to the same server. In this case, the user would be presented with the login screen again. The typical solution would be to use sticky sessions. But, we will still have the problem as we lose the session data on a server crash.
To solve these problems, need to share the session information with the other server instances. Thanks to spring-session module it is as easy as adding a bunch of dependencies, and little configuration. As we saw earlier in the redis cache implementation, Redis is a high-performance memory-based data store that we can use for fast storing and retrieval of key-value pair. The Spring session module can turn this Redis datastore into a session store.
To enable the Redis integration, you need to bring in
spring-boot-starter-data-redis dependency to your existing
spring boot application. To make sure spring session features to use Redis you need to add the To enable Redis store,
you need to bring in
dependency. To make sure spring session features to use redis you need to add the
<dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> <dependency> <groupId>org.springframework.session</groupId> <artifactId>spring-session-data-redis</artifactId> </dependency>
As you see, there is not a single line of code to be added in spring boot project if you followed the defaults.
Also, I’m using the following docker-compose.yml to run a Redis server and redis-commander to view the content in Redis.
version: '3' services: redis: container_name: redis hostname: redis image: redis ports: - "6379:6379" redis-commander: container_name: redis-commander hostname: redis-commander image: rediscommander/redis-commander:latest restart: always environment: - REDIS_HOSTS=local:redis:6379 ports: - "8081:8081"
after creating docker-compose.yml you can start the server using the following command.
docker-compose docker-compose.yml up -d
Note that this segment is for setting up things in localhost. But you can still run the Redis-commander for viewing the content. All you have to do is to change the Redis host accordingly.
Once the server is up you can navigate to http://localhost:8081/ on the browser to access the RedisCommander GUI.
Once we added the dependencies, the final step is to point the application to the Redis server. For this, you need to add the following properties.
spring.session.store-type=redis spring.redis.host=localhost spring.redis.port=6379
spring.session.store-typecan be ignored as the auto-configuration will detect the
redis-starterdependency and configure this value automatically to
However, If you have multiple
spring-session-data-*dependencies, then you need to specify a value for this property.
Some Redis servers may have a password for that use
spring.redis.port. For more, Redis related properties head down to
the spring boot documentation for all application properties
On the right side of the above view, you can see the session attributes usually in gibberish (these are in java serialized objects format).
Whenever the server needs to check the session detail, these data gets created and updated. When another application connects to same Redis server, that application can start serving authenticated requests as the session details are available for the new server as well.
Also, note that the Redis server keeps the session information even when the application crashes. Thus, the user doesn’t need to log in again on server restarts.
The sample code base for this example is in the Github link below.
In the above screenshot you can see that the default path(namespace) where the sessions are stored is
You can override this path to be different using
spring.session.redis.namespace configuration property.