nginx solves session consistency

Posted by ckjian on Sun, 05 May 2019 09:00:05 +0200

  1. session viscosity
  • Each request is allocated according to the hash result of accessing ip, so that each visitor can access a back-end server regularly, which can solve the session problem.  
  • upstream backserver {
    ip_hash;
    server 192.168.0.14:88;
    server 192.168.0.15:80;
    }
  • However, there is a single risk. If I have logged in at port 192.168.0.14:88 and found that 14 servers are dead (session time is not expired), then I will visit 15 servers. At this time, I need to log in again, because I need to take JsessionId on 14 servers to 15 servers to request that it does not exist.

2. session replication

  • You can configure it through the server.xml file of tomcat so that each tomcat synchronizes the corresponding session, then even if a tomcat is down, it will not affect the service.
  • Specific tomcat can be seen below. tomcat cluster configuration corresponding to tomcat official network
  • <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>

3. session sharing (spring boot)

  • Adding pom files to corresponding projects
  • <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 @Enable RedisHttpSession to open spring session support
  • @Configuration  
    @EnableRedisHttpSession  
    public class RedisSessionConfig {  
    } 
  • Interface for adding validation
  • @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 look at redis cached data
  • Session Id can be found cached in redis database
  • Now let's change the port and visit it again.
  • This time I changed the port to 8888: http://localhost:8888/session
  • The redis database was refreshed and the cached data remained unchanged
  • The SessionId in the results is the same, but it is provided by two different project projects. In this way, SpringSession uses the interceptor Filter to help us synchronize the settings before each request to achieve session sharing in distributed systems.

4. session Sharing

Topics: Programming Session Apache Redis Tomcat