springboot (eighteen) -session Share

Foreword

In conventional single service architecture, in general, only one server, it does not share Session problems, but in a distributed / cluster projects, the Session sharing is a problem to be faced, we look at a simple architecture diagram :

In this architecture, there will be some single service problem does not exist, for example, the client initiates a request, the request after arriving on Nginx, is forwarded Nginx on Tomcat A, then to the session is saved in a on Tomcat A parts of the data, again a next request, the request is forwarded to the Tomcat B, at this time go Session acquired data, before the data is not found. For solving this kind of problem, the idea is very simple, is the need to share data between the various services, saved to a public place (mainstream programs that Redis):

When all Tomcat need to write data to the Session, both Redis to write, when all Tomcat need to read the data are read from the Redis. In this way, different services can use the same Session data.

Such solutions can be achieved manually by the developer, which store data manually to Redis, the manual reads data from Redis, the equivalent to using some of the Redis client tools to achieve this function, no doubt, done manually or workload pretty big.

A simplified scheme is used to achieve this function Session Spring, Spring Session proxy filter is used in the Spring, all operations Session intercepted, the data will be automatically synchronized to the Redis, or automatically read from the Redis data.

For developers, all about Session synchronous operation is transparent, developers use the Spring Session, once the configuration is complete, specific usage like using an ordinary Session same.

 

Real

1. Create a springboot project, add dependencies

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.0.0.RELEASE</version>
        <relativePath/> <!-- lookup parent from repository -->
    </parent>
    <groupId>org.javaboy</groupId>
    <artifactId>sessionshare</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>sessionshare</name>
    <description>Demo project for Spring Boot</description>

    <properties>
        <java.version>1.8</java.version>
    </properties>

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

    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>

</project>

2.配置application.properties或者.yml文件

spring.redis.host=localhost
spring.redis.port=6379
spring.redis.password=
spring.redis.database=0

server.port=8082

我们再这个文件中配置下redis。

3.提供接口文件

package org.javaboy.sessionshare;

import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.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;
    }
}

简单说下,@Value("{server.port}") 如果我们不指定端口,直接启动该实例,那么port = 8082 (application.properties文件中有写),如果我们指定端口启动该实例,那port就是我们指定的端口了。具体的用法下面有。

我们只提供两个接口,一个set和一个get。字面上就能明白,不做赘言。

4.启动类

package org.javaboy.sessionshare;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

@SpringBootApplication
public class SessionshareApplication {

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

}

 

测试

启动redis服务

我们在终端cd 到项目目录

  mvn install

  java -jar target/sessionshare-0.0.1-SNAPSHOT.jar --server.port=8080

再启动一个终端cd 到项目目录

  java -jar target/sessionshare-0.0.1-SNAPSHOT.jar --server.port=8081

指定端口启动两个实列。

浏览器访问 localhost:8080/set  ,  你会看到页面上显示8080,我们已经set完了。数据已经保存到redis中。

然后访问 localhost:8081/get , 看到页面上显示 

javaboy:8081

说明我们取到了redis中的数据。

此时关于 session 共享的配置就已经全部完成了,session 共享的效果我们已经看到了,但是每次访问都是我自己手动切换服务实例,因此,接下来我们来引入 Nginx ,实现服务实例自动切换。

 

引入 Nginx

编辑 nginx.conf 文件:

upstream springboot{
    server 127.0.0.1:8080 weight=1;
    server 127.0.0.1:8081 weight=2;
    }

    server {
        listen       9000;
        server_name  localhost;

        #charset koi8-r;

        #access_log  logs/host.access.log  main;

        location / {
            proxy_pass http://springboot;
        }

在这段配置中:

  1. upstream 表示配置上游服务器
  2. springboot表示服务器集群的名字,这个可以随意取名字
  3. upstream 里边配置的是一个个的单独服务
  4. weight 表示服务的权重,意味者将有多少比例的请求从 Nginx 上转发到该服务上
  5. location 中的 proxy_pass 表示请求转发的地址,/ 表示拦截到所有的请求,转发转发到刚刚配置好的服务集群中

  

配置完成后,启动nginx,和上面两个springboot实例。

因为我的nginx端口是9000,且在本地,

多次访问localhost:9000/set,多次访问localhost:9000/get.

看页面结果,我们即实现了redis中保存和读取session中的值,也实现了负载均衡。

2 总结

本文主要向大家介绍了 Spring Session 的使用,另外也涉及到一些 Nginx 的使用 ,虽然本文较长,但是实际上 Spring Session 的配置没啥。

我们写了一些代码,也做了一些配置,但是全都和 Spring Session 无关,配置是配置 Redis,代码就是普通的 HttpSession,和 Spring Session 没有任何关系!

唯一和 Spring Session 相关的,可能就是我在一开始引入了 Spring Session 的依赖吧!

如果大家没有在 SSM 架构中用过 Spring Session ,可能不太好理解我们在 Spring Boot 中使用 Spring Session 有多么方便,因为在 SSM 架构中,Spring Session 的使用要配置三个地方 ,一个是 web.xml 配置代理过滤器,然后在 Spring 容器中配置 Redis,最后再配置 Spring Session,步骤还是有些繁琐的,而 Spring Boot 中直接帮我们省去了这些繁琐的步骤!不用再去配置 Spring Session。

 

代码下载地址:https://gitee.com/fengyuduke/my_open_resources/blob/master/sessionshare.zip

 

本文出处:https://www.cnblogs.com/lenve/p/10971384.html#4272530

 

Guess you like

Origin www.cnblogs.com/fengyuduke/p/10979053.html
Recommended