Nginx series tutorials nginx Solving session consistency

Posted by djelica on Sun, 12 Apr 2020 03:53:23 +0200

session viscosity

Each request is allocated according to the hash result of the access ip, so that each visitor accesses a back-end server, which can solve the session problem.

upstream backserver {
ip_hash;
server 192.168.0.14:88;
server 192.168.0.15:80;
}

But there are disadvantages. There is a single risk. If I have logged in on port 192.168.0.14:88 and found that the 14 server is hung after a period of time (the session time has not expired), then I will visit the 15 server at this time. At this time, I need to log in again, because when I go to the 15 server with the JsessionId on the 14 server to request to find that it does not exist.

In the nginx configuration file, add configuration, HASH the IP to the server.

This implementation is the simplest. But for the front-end deployed with SBC, or many requests are from an external gateway, it is useless. It is also not easy to use if the app will switch wifi to ip.

session replication

It can be configured through the server.xml file of tomcat, so that each Tomcat will synchronize the corresponding session, so even if a Tomcat is down at this time, the service will not be affected.

See the following for specific tomcat, tomcat cluster configuration corresponding to tomcat official website

In tomcat's web.xml, it is configured as a cluster mode,
Configure the cluster information in tomcat's server.xml.

After configuration, the session can be copied automatically.

The disadvantage is that each server needs to save a full amount of session information, which is basically unavailable when there are many servers. But the development is simple, when there are only two or three servers, it is OK.

<Cluster className="org.apache.catalina.ha.tcp.SimpleTcpCluster"
                 channelSendOptions="8">

          <Manager className="org.apache.catalina.ha.session.DeltaManager"
                   expireSessionsOnShutdown="false"
                   notifyListenersOnReplication="true"/>

          <Channel className="org.apache.catalina.tribes.group.GroupChannel">
            <Membership className="org.apache.catalina.tribes.membership.McastService"
                        address="228.0.0.4"
                        port="45564"
                        frequency="500"
                        dropTime="3000"/>
            <Receiver className="org.apache.catalina.tribes.transport.nio.NioReceiver"
                      address="auto"
                      port="4000"
                      autoBind="100"
                      selectorTimeout="5000"
                      maxThreads="6"/>

            <Sender className="org.apache.catalina.tribes.transport.ReplicationTransmitter">
              <Transport className="org.apache.catalina.tribes.transport.nio.PooledParallelSender"/>
            </Sender>
            <Interceptor className="org.apache.catalina.tribes.group.interceptors.TcpFailureDetector"/>
            <Interceptor className="org.apache.catalina.tribes.group.interceptors.MessageDispatchInterceptor"/>
          </Channel>

          <Valve className="org.apache.catalina.ha.tcp.ReplicationValve"
                 filter=""/>
          <Valve className="org.apache.catalina.ha.session.JvmRouteBinderValve"/>

          <Deployer className="org.apache.catalina.ha.deploy.FarmWarDeployer"
                    tempDir="/tmp/war-temp/"
                    deployDir="/tmp/war-deploy/"
                    watchDir="/tmp/war-listen/"
                    watchEnabled="false"/>

          <ClusterListener className="org.apache.catalina.ha.session.ClusterSessionListener"/>
        </Cluster>

session sharing (springboot)

Add pom file in corresponding project

<dependency>  
        <groupId>org.springframework.boot</groupId>  
        <artifactId>spring-boot-starter-redis</artifactId>  
</dependency>  
<dependency>  
        <groupId>org.springframework.session</groupId>  
        <artifactId>spring-session-data-redis</artifactId>  
</dependency>  

Configure redis information in the corresponding application.properties

spring.redis.host=localhost
spring.redis.port=6379

Add the annotation @ enablereredishttpsession to enable spring session support

@Configuration  
@EnableRedisHttpSession  
public class RedisSessionConfig {  
} 

Add verified interface

@Value("${server.port}")
    String port;

    @GetMapping("/session")
    public Object getSession(HttpServletRequest request){
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("SessionId", request.getSession().getId());
        map.put("ServerPort", "The service port number is "+port);
        return map;
    }

Visit http://localhost:8080/session

Let's change the port and visit again
This time I changed the port to 8888 access: http://localhost:8888/session


The redis database has been refreshed, and the cached data has not changed

The SessionId in the result is the same, but it is served by two different project projects. In this way, spring session uses interceptor Filter to help us set up synchronization before each request to achieve session sharing in the distributed system.

session sharing (springmvc)

First, add the corresponding jar in the pom.xml file

<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>

Configure in the corresponding springmvc-context.xml 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" />
        <property name="testOnBorrow" value="true" />
    </bean>

    <bean id="connectionFactory"  class="org.springframework.data.redis.connection.jedis.JedisConnectionFactory" >
        <property name="poolConfig" ref="jedisPoolConfig" />
        <property name="port" value="6379" />
        <property name="hostName" value="192.168.1.11" />
        <property name="password" value="xxx" />
        <property name="timeout" value="30000" ></property>
    </bean >

    <bean id="redisTemplate" class="org.springframework.data.redis.core.RedisTemplate" >
        <property name="connectionFactory" ref="connectionFactory" />
        <property name="keySerializer">
            <bean  class="org.springframework.data.redis.serializer.StringRedisSerializer" />
        </property>
        <property name="valueSerializer">
            <bean class="org.springframework.data.redis.serializer.StringRedisSerializer" />
        </property>
    </bean >

    <bean id="redisUtil" class="com.isea533.mybatis.service.RedisUtil" >
        <property name="redisTemplate" ref="redisTemplate" />
    </bean >

Secondly, configure it in web.xml (it is very important that the name of filter must be springSessionRepositoryFilter)

  <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>

Access project path rendering results


Previous articles

Nginx series tutorial (1) basic introduction and installation of nginx
Nginx series tutorial (2) nginx building static resource web server
Nginx tutorial series (3) static files on nginx cache server
Nginx series tutorials (4) nginx deals with load balancing of web applications to ensure high concurrency
Nginx series tutorial (5) how to ensure the high availability of nginx
Nginx series of tutorials (6) detailed explanation of nginx location matching rules
Nginx series(7)Detailed description of nginx rewrite configuration rules
Nginx series tutorial (8) nginx configuring security certificate SSL

Topics: Web Server Session Redis Apache Nginx