Java Spring Recruitment Interview Question Answer Series: Implementation of Distributed Session Scheme

1 Interview questions

How to implement distributed session in cluster deployment?

2 Introduction to Session

The browser has a cookie. This cookie exists for a period of time, and every time a request is sent, it will bring a special jsessionid cookie. Based on this thing, a corresponding session domain can be maintained on the server side, and a bit can be placed in it.儿数据。 Child data.

Generally, as long as you do not close the browser and the cookie is still there, the corresponding session is there, but if the cookie is gone, the session is gone. Commonly found in shopping carts and the like, as well as login status preservation and the like.

It’s okay to play sessions like this in a single block system, but if you are a distributed system, where is the session state maintained for so many services?

In fact, there are many methods, but there are two common and commonly used methods:

3 Implementation plan

3.1 Tomcat + Redis

This is actually quite convenient, that is, the code for using the session is the same as before, or based on Tomcat's native session support, and then a thing called Tomcat RedisSessionManager is used, so that all the Tomcats we deploy will store the session data in redis. can.

In the Tomcat configuration file, configure

<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />

<Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
         host="{redis.host}"
         port="{redis.port}"
         database="{redis.dbnum}"
         maxInactiveInterval="60"/>

Just make a configuration similar to the above, you can see if you use RedisSessionManager, and then specify the host and port of redis.

<Valve className="com.orangefunction.tomcat.redissessions.RedisSessionHandlerValve" />
<Manager className="com.orangefunction.tomcat.redissessions.RedisSessionManager"
	 sentinelMaster="mymaster"
	 sentinels="<sentinel1-ip>:26379,<sentinel2-ip>:26379,<sentinel3-ip>:26379"
	 maxInactiveInterval="60"/>

You can also use the above method to save session data based on the redis high-availability cluster supported by redis sentinel, all of which are ok

3.2 Spring Session + Redis

The distributed session is re-coupled in tomcat. If I want to migrate the web container to jetty, do you configure all jetty again?

Because the above tomcat + redis method is easy to use, but it will rely heavily on web containers , and it is not easy to port the code to other web containers, especially if you change the technology stack? For example, replacing it with spring cloud or spring boot.

So now it is better to be a one-stop solution based on java, spring!
People spring basically packaged most of the frameworks we need to use, spirng cloud is used as microservices, and spring boot is used as scaffolding, so use sping session Is a good choice

  • pom.xml
<dependency>
  <groupId>org.springframework.session</groupId>
  <artifactId>spring-session-data-redis</artifactId>
  <version>1.2.1.RELEASE</version>
</dependency>
<dependency>
  <groupId>redis.clients</groupId>
  <artifactId>jedis</artifactId>
  <version>2.8.1</version>
</dependency>
  • spring configuration file
<bean id="redisHttpSessionConfiguration"
     class="org.springframework.session.data.redis.config.annotation.web.http.RedisHttpSessionConfiguration">
    <property name="maxInactiveIntervalInSeconds" value="600"/>
</bean>

<bean id="jedisPoolConfig" class="redis.clients.jedis.JedisPoolConfig">
    <property name="maxTotal" value="100" />
    <property name="maxIdle" value="10" />
</bean>

<bean id="jedisConnectionFactory"
      class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" destroy-method="destroy">
    <property name="hostName" value="${redis_hostname}"/>
    <property name="port" value="${redis_port}"/>
    <property name="password" value="${redis_pwd}" />
    <property name="timeout" value="3000"/>
    <property name="usePool" value="true"/>
    <property name="poolConfig" ref="jedisPoolConfig"/>
</bean>
  • web.xml
<filter>
    <filter-name>springSessionRepositoryFilter</filter-name>
    <filter-class>org.springframework.web.filter.DelegatingFilterProxy</filter-class>
</filter>
<filter-mapping>
    <filter-name>springSessionRepositoryFilter</filter-name>
    <url-pattern>/*</url-pattern>
</filter-mapping>
  • Sample code
@Controller
@RequestMapping("/test")
public class TestController {
    
    

@RequestMapping("/putIntoSession")
@ResponseBody
    public String putIntoSession(HttpServletRequest request, String username){
    
    
        request.getSession().setAttribute("name",  “leo”);

        return "ok";
    }

@RequestMapping("/getFromSession")
@ResponseBody
    public String getFromSession(HttpServletRequest request, Model model){
    
    
        String name = request.getSession().getAttribute("name");
        return name;
    }
}

The above code is ok. Configure the sping session to store session data based on redis, and then configure a spring session filter. In this case, the session-related operations will be handled by spring session.
Then in the code, just use The native session operation is to get data from redis directly based on spring sesion.

3.3 Summary

  • What is

    a distributed session? There are many, many ways to implement a distributed session, but here are two more common ways.
    Tomcat + redis is more commonly used in the early days, but it will be re-coupled to tomcat in
    recent years, through spring session to fulfill.

Guess you like

Origin blog.csdn.net/weixin_43314519/article/details/112446583