The Spring-Session SpringBoot implemented using shared session (nginx + redis)

A, Spring-Session scene using

HttpSession is created and managed by the Servlet container, in a single environment. Session Http request information created by the Web server are stored in memory, such as Tomcat / Jetty. If the browser when the user accesses the application server, session information stored in the user's login information, and session information is not to expire, has been in effect then the user logged in, you can do some of the login status of business operations.

But now many of the servers are distributed by way of a cluster deploy a Web application, it may be deployed on several different servers, load balancing (generally use Nginx + Tomcat load balancing) by LVS or Nginx and so on. At this http request from the same user will likely be distributed to different web sites to (eg: first assigned to the A site, the second site may be assigned to B). So the question becomes, how to ensure that different web sites to share data with a session it?

If the user initiating the first request when visiting the A site and save login information in a session A site, when a user initiates a second request, assigned to site B through load balancing requests, then this time B site can No access to information stored in the user log it? The answer is no, as explained above, the corresponding session is stored in the Web server's memory can not be shared at this time spring-session appeared to help us solve this session sharing problem!

 

 

How Session to share it?

Simple point that is requested through http request Filter chain configuration information filter according to claim session creation of a spring-session by the SessionRepository tomcat, session created by spring-session, Session unified content stored in a database (e.g. MySQL) or buffer (e.g. Redis, Mongo) in.

 

Of course, using the Nginx ip_hash strategy can also solve the problem of synchronization session.

In using the Nginx ip_hash strategy when each request assigned by hash result Access ip so that each visitor to access a back-end server is fixed, this would resolve the problem of synchronizing the session.

Great God article addresses: https://blog.csdn.net/qq_28602957/article/details/61615876

Second, the use of spring-session in springboot

1, rely on the introduction of Maven

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
       <!--spring boot-->
       <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <!--spring session-->
    <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>
    </dependencies>         

2, the configuration application.properties

8080 = the server.port 
spring.redis.host = localhost 
spring.redis.port = 6379 

#spring the session using the storage type, the default is redis may be omitted 
spring.session.store -type = redis

3, add annotation startup class

@EnableCaching
@EnableRedisHttpSession
@SpringBootApplication
public class SpringsessionApplication {

    public static void main(String[] args) {
        SpringApplication.run(SpringsessionApplication.class, args);
    }

}

4, write controller

import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpServletRequest;

@RestController
public class IndexController {

    @RequestMapping("/show")
    public String show(HttpServletRequest request){
        return "I'm " + request.getLocalPort();
    }


    @RequestMapping(value = "/session")
    public String getSession(HttpServletRequest request) {
        request.getSession().setAttribute("userName", "admin");
        return "I'm " + request.getLocalPort() + " save session " + request.getSession().getId();
    }

    @RequestMapping(value = "/get")
    public String get(HttpServletRequest request) {
        String userName = (String) request.getSession().getAttribute("userName");
        return "I'm " + request.getLocalPort() + " userName :" + userName;
    }
    
}

5, configure nginx

    upstream  ngixServers{
        server localhost:8081;
        server localhost:8082;
    }
    server {
        listen       8888;
        server_name  localhost;
        location / {
        proxy_pass http://ngixServers;
        }
    }

6, the test results

a) Start redis

b) start nginx

c) modify the springboot startup mode, a plurality of sample allowed to start.

d) modify the port number in application.properties, 8081 to start tomcat.

e) the port number of application.properties, 8082 to start tomcat.

Access Address: HTTP: // localhost: 8888 / Show   visible results are as follows (in no particular order appears):

 Refresh visible:

 Responsible for running the above results show that already balanced so that, both servers can access.

f) The next access address: HTTP: // localhost: 8888 / session , the session writes a server. (Server may be 8081, it could be 8082)

 g)访问地址:http://localhost:8888/get ,多次刷新可见两个服务器均能获得session。(此session存在与redis中)

 

或者

 

 到此,使用nginx实现负载均衡和使用spring-session+redis实现session同步就完成了。

  

参考大神文章:

https://www.cnblogs.com/aflyun/p/8532210.html

https://www.cnblogs.com/shyroke/p/8039430.html

 

Guess you like

Origin www.cnblogs.com/david1216/p/11468772.html