Some people may feel that the title is a bit exaggerated, but it is not exaggerated, the title does not use any rhetorical devices! Read this article carefully and you’ll know That Songo is right!

In a traditional single-server architecture, generally speaking, there is only one server, so there is no Session sharing problem. However, in distributed/cluster projects, Session sharing is an issue that must be faced. Let’s look at a simple architecture diagram:

In such an architecture, there are some problems that do not exist in A single service. For example, the client initiates A request, which arrives at Nginx, is forwarded to Tomcat A, which stores A copy of the data into the session, and the next request comes, The request is forwarded to Tomcat B, which then goes to Session to retrieve the data and finds that there is no previous data. To solve this problem, the idea is simple: save the data that needs to be shared between various services in a public place (the mainstream solution is Redis) :

When Tomcat needs to write to Session, it writes to Redis, and when Tomcat needs to read data, it reads from Redis. In this way, different services can use the same Session data.

Such a scheme, can be manually implemented by developers, that is, manually store data in Redis, manually read data from Redis, equivalent to the use of some Redis client tools to achieve such a function, there is no doubt that manual implementation of the workload is quite large.

A simplified solution is to use Spring Session to implement this function. Spring Session uses the Spring proxy filter to intercept all Session operations and automatically synchronize data to Redis. Or automatically read data from Redis.

All Session synchronization operations are transparent to developers, who use Spring Sessions and, once configured, use them as if they were using a normal Session.

1 combat

1.1 Creating a Project

Start with a Spring Boot project that introduces Web, Spring Session, and Redis:

After successful creation, the pom.xml file looks like this:

<dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-data-redis</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
    </dependency>
    <dependency>
        <groupId>org.springframework.session</groupId>
        <artifactId>spring-session-data-redis</artifactId>
    </dependency>
</dependencies>
Copy the code

Note:

I’m using Spring Boot version 2.1.4. If I’m using the current Spring Boot2.1.5, I need to add a Spring Security dependency in addition to these dependencies. Of course, some of Spring Security’s default authentication processes are added.

1.2 configure Redis

Spring. Redis. Host = 192.168.66.128 spring. Redis. Port = 6379 spring. Redis. Password = 123 spring. Redis. Database = 0Copy the code

Although I configured four lines of Redis here, considering that the default port is 6379 and the default database is 0, what I really need to configure is two lines.

1.3 the use of

Spring Session (HttpSession); HttpSession (Redis); HttpSession (HttpSession);

@RestController
public class HelloController {
    @Value("${server.port}")
    Integer port;
    @GetMapping("/set")
    public String set(HttpSession session) {
        session.setAttribute("user"."javaboy");
        return String.valueOf(port);
    }
    @GetMapping("/get")
    public String get(HttpSession session) {
        return session.getAttribute("user") + ":"+ port; }}Copy the code

Considering that Spring Boot will be started in cluster mode later, in order to get which Spring Boot service is provided by each request, we need to return the port number of the current service on each request, so HERE I inject server.port.

Next, project packaging:

After packaging, start two instances of the project:

Java -jar sessionshare-0.0.1 -snapshot. jar --server.port=8080 Java -jar sessionshare-0.0.1 -snapshot.jar --server.port=8081Copy the code

Localhost :8080/set = localhost:8080/set = localhost:8080/set

Localhost :8081/get (localhost:8081/get);

We have already seen the effect of session sharing, but each time I have to manually switch service instances. Therefore, let’s introduce Nginx to implement automatic switching service instances.

1.4 introduced Nginx

Simply go to the Nginx installation directory conf directory (default: /usr/local/nginx/conf) and edit the nginx.conf file:

In this configuration:

  1. Upstream: configures the upstream server
  2. Javaboy.org indicates the name of the server cluster, which can be arbitrarily named
  3. Separate services are configured in upstream
  4. Weight represents the weight of the service, which means what percentage of requests will be forwarded to the service from Nginx
  5. Proxy_pass in location represents the address requested for forwarding,/All requests are intercepted and forwarded to the newly configured service cluster
  6. Proxy_redirect indicates that nginx automatically corrects the response header data when a redirect request occurs.

After the configuration is complete, upload the local Spring Boot packaged JAR to Linux, and then start two Spring Boot instances on Linux:

Port = 8080&nohup java-jar sessionshare-0.0.1 -snapshot.jar --server.port= 8080&nohup java-jar sessionshare-0.0.1 -snapshot.jar --server.port=8081 &Copy the code

Among them

  • Nohup indicates that Spring Boot should not stop running when the terminal is shut down
  • & enables Spring Boot to start in the background

After the configuration is complete, restart Nginx:

/usr/local/nginx/sbin/nginx -s reload
Copy the code

After Nginx is successfully started, we first manually clean the data on Redis, and then access 192.168.66.128/set to save data to the session. This request is first sent to Nginx. Nginx forwards it to a Spring Boot instance:

Spring Boot with port 8081 processes the /set request and then accesses /get:

As you can see, the/GET request is handled by the service with port 8080.

2 summary

This article mainly introduces the use of Spring Session, and also covers some Nginx use. Although this article is long, the actual configuration of Spring Session is not much.

We wrote some code and did some configuration, but it has nothing to do with Spring Session, the configuration is to configure Redis, the code is normal HttpSession, has nothing to do with Spring Session!

The only thing associated with Spring Session is that I introduced the Spring Session dependency in the first place.

For those of you who have not used Spring Sessions in the SSM architecture, it may not be easy to understand how convenient it is to use Spring Sessions in Spring Boot, because in the SSM architecture, To use Spring Session, you need to configure three places, one is web. XML configure proxy filter, then configure Redis in the Spring container, and finally configure Spring Session. The steps are still a little tedious. Spring Boot directly saves us these tedious steps! There is no need to configure Spring Session.

Well, that’s all for this article. Related cases in this article have been uploaded to GitHub, and you can download them by yourself :github.com/lenve/javab…

Pay attention to the public account [Jiangnan little Rain], focus on Spring Boot+ micro service and front and back end separation and other full stack technology, regular video tutorial sharing, after attention to reply to Java, get Songko for you carefully prepared Java dry goods!