六、Spring Boot 整合 NoSQL(4)

本章概要

  • Session 共享

6.3 Session 共享

正常情况下,HttpSession 是通过 Servlet 容器创建进行管理的,创建成功之后都是保存在内存中。如果开发者需要对项目进行横向扩展搭建集群,那么可以利用一些硬件或者软件工具来做负载均衡,此时,来自同一用户的 HTTP 请求就有可能被分发都不同的实例上去,如何保证各个实例之间的 Session 的同步就成为一个必须要解决的问题。
Spring Boot 提供了自动化的 Session 共享配置,它结合 Redis 可以非常方便地解决这个问题。使用 Redis 解决 Session 共享的原理非常简单,就是把原本存储在不同服务器上的 Session 拿出来放在一个独立的服务器上,如图(画的不好,凑合看)。
在这里插入图片描述

当一个请求到达 Nginx 服务器后,首先进行请求分发,假设请求分到 A 了,A 在 处理请求时,无论是存储 Session 还是读取 Session ,都去操作 Session 服务器而不是操作自身的内存中的 Session ,其它应用服务器在处理请求时也是如此,这样就实现 Session 共享了。

6.3.1 Session 共享配置

Spring Boot 中的 Session 共享配置非常容易,创建Spring Boot Web 项目,添加 Redis 和 Session 依赖,如下:

<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-data-redis</artifactId>
  <exclusions>
    <exclusion>
      <groupId>io.lettue</groupId>
      <artifactId>lettuce-core</artifactId>
    </exclusion>
  </exclusions>
</dependency>
<dependency>
  <groupId>redis.clients</groupId>
  <artifactId>jedis</artifactId>
</dependency>
<dependency>
  <groupId>org.springframework.session</groupId>
  <artifactId>spring-session-data-redis</artifactId>
</dependency>

除了 Redis 依赖之外,这里还要提供 spring-session-data-redis 依赖,Spring Session可以做到透明化地替换掉应用的 Session 容器。项目创建成功后,在 application.properties 中进行 Redis 基本连接信息配置

spring.redis.database=0
spring.redis.host=ip地址
spring.redis.port=6379
spring.redis.password=123456
spring.redis.jedis.pool.max-active=8
spring.redis.jedis.pool.max-idle=8
spring.redis.jedis.pool.max-wait=-1ms
spring.redis.jedis.pool.min-idle=0

然后创建一个 Controller 用来执行测试操作

@RestController
public class HelloController {
    
    
    @Value("${server.port}")
    String port;
    @PostMapping("/save")
    public String saveName(String name, HttpSession session) {
    
    
        session.setAttribute("name", name);
        return port;
    }
    @GetMapping("/get")
    public String getName(HttpSession session) {
    
    
        return port + ":"
                + session.getAttribute("name").toString();
    }
}

这里提供了两个方法,一个 save 接口用来向 Session 中存储数据,还有一个 get 接口用来从 Session 中获取数据,这里注入了项目启动的端口号 server.port ,主要是为了区分到底是哪个服务器提供的服务。另外,虽然还是操作的 HttpSession,但是实际上 HttpSession 容器已经被透明替换,真正的 Session 此时存储在 Redis 服务器上。
项目创建完成后,将项目打成 jar 包上传到 CentOS 上。然后执行如下两条命令启动项目:

nohup java -jar a.jar --server.port=8080 &
nohup java -jar a.jar --server.port=8081 &

nohup 表示不挂断程序运行,即当终端窗口关闭后,程序依然在后台运行,最后的 & 表示让程序在后台运行。 – server.port 指定启动的端口号。启动成功后开始配置负载均衡。
在这里插入图片描述

6.3.2 Nginx 负载均衡

先在 CentOS 上安装 Nginx ,下载源码并解压:

wget https://nginx.org/download/nginx-1.14.0.tar.gz
tar -zxvf /opt/package/nginx-1.14.0.tar.gz -C /opt/soft/

然后进入目录,编译安装

cd /opt/soft/nginx-1.14.0
./configure
make
make install

安装成功后,找到 Nginx 安装目录,执行 sbin 目录下的 nginx 文件启动ngxin

/usr/local/nginx/sbin/nginx

Nginx 启动成功后,默认端口是 80 ,可以在物理机直接访问
在这里插入图片描述

然后修改 Nginx 的配置文件

vim /usr/local/nginx/conf/nginx.conf

编辑内容如下


worker_processes  1;
events {
    worker_connections  1024;
}


http {
    include       mime.types;
    default_type  application/octet-stream;
    sendfile        on;
    keepalive_timeout  65;
    
    upstream myserver {
		server ip地址:8080 weight=1;
		server ip地址:8081 weight=1;
	}
    
    server {
		listen 80;
		server_name 127.0.0.1 localhost ip地址;
		location / {
			proxy_pass http://myserver;
			root html;
			index index.html index.htm;
		}
	}

}

然后重启 Nginx

/usr/local/nginx/sbin/nginx -s reload

6.3.3 请求分发

当 real server 和 ngxin 都启动后,调用 “/save” 接口存储数据
在这里插入图片描述

调用的端口是 80 ,即调用的是 Nginx 服务器,请求会被 Nginx 转发到 real server 上进行处理,返回值为 8080 ,说明真正处理请求的 real server 是 8080 那台服务器,接下来调用 get 接口获取数据

在这里插入图片描述

调用的端口依然是 80 ,但是返回值是 8081 ,说明是 8081 那台 real server 提供的服务,如果者里不是 8081 ,再访问一次即可。
经过如上步骤,就完成了利用 Redis 实现 Session 共享功能,基本上不需要额外配置,开箱即用。

猜你喜欢

转载自blog.csdn.net/GXL_1012/article/details/126173768