本文是读《Spring Boot2精髓-从构建小系统到架构分布式大系统》的读书笔记。
Spring Boot 应用通常会部署在多个 Web 服务器上同时提供服务。
- 单个应用者机不会停止服务,升级应用可以逐个升级而不必停止服务 。
- 提高了应用整体的吞吐量 。
我们称这种部署方式为水平扩展,前端通过 Nginx 提供反向代理 , 会话管理可以通过 Spring
Session ,使用 Redis 来存放 Session 。 部署 Spring Boot 应用到任意 一 台 Web 服务器上 ,从而提高了系统可靠性和可伸缩性 。
15.1 水平扩展实现
Spring Boot应用水平扩展有两个问题需要解决,一个是将用户的请求派发到水平部署的任意一台Spring Boot 应用,通常用一个反向代理服务器来实现,本书将使用Nginx作为反向代理服务器。
另外一个需要解决的问题是会话管理, 单个 Spring Boot 应用的会话由 Tomcat 来管理,会
话信息与 Tomcat 存放在一起。如果部署多个 Spring Boot 应用,对于同一个用户请求,即使请
求通过 Nginx 派发到不同的 Web 服务器上,也能共享会话信息。有两种方式可以实现 。
- 复制会话 : Web 服务器通常都支持 Session 复制 , 一 台应用的会话信息改变将立刻复制到其他集群的 Web 服务器上。
- 集中式会话 : 所有 Web 服务器都共享一个会话,会话信息通常存放在一 台服务器上
15.2 Nginx的安装和配置
安装Nginx
http://nginx.org/
以下是 Nginx 的常用命令 :
nginx , 启动 Nginx , 默认监听 80 端口 。
nginx -s stop,快速停止服务器 。
nginx -s quit , 停止服务器,但要等到请求处理完毕后关闭 。
nginx -s reload , 重新加载配置文件。
配置Nginx
Nginx的配置文件conf/nginx.conf下包含多个指令块,我们主要关注 http块和location 块。
由于本章主要是讲水平扩展 Spring Boot 应用,因此,我们需要在 http 块中增加 upstream 指令,内容如下 :
http {
upstream backend {
server 127 . 0.0 . 1:9000 ;
server 127 . 0.0.1 : 9001
}
}
backe nd 也可以为任意名字,我们在下面的配置将要引用到 :
location / {
proxy pass http : //backend ;
}
整个 http 块
http {
include mime.types ;
default type application/octet- stream ;
sendfile on;
keepalive timeout 65 ;
upstream backend {
server 127.0 . 0.1:9000;
server 127.0.0.1:9001 ;
server {
listen 80 ;
server name localhost ;
location I {
proxy pass http : //backend;
}
}
}
Nginx 反向代理默认情况下会轮询后台应用,另一种配置是设置 ip_hash
15.3 Spring Session
Spring Session介绍
在默认情况下, Spring Boot 使用 Tomcat 服务器的 Session 实现。
在配置文件 application.properties 中添加如下内容:
spring.session.store-type=Redis|JDBC|Hazelcast|none
//上面四个是并列的
Spring Boot 配置很容易切换到不同的 Session 管理方式 , 总共有以下几种 :
- Redis, Session 数据存放 Redis 中。
- JDBC , 会话数据存放在数据库中,默认情况下
- SPRING SESSION 表存放 Session 基 本信息 ,如 sessionld 、创建时间、 最后一次访问时间等 , SPRING_ SESSION_ATTRIBUTES存放了 session 数据 , ATTRIBUTE_NAME 列保存了 Session 的 Key ,ATTRIBUTE_BYTES 列以字节形式保存了 Session 的 Value, Spring Session 会自动创 建这两张表。
- Hazelcast, Session 数据存放到 Hazeleast 。
- None,禁用 Spring Session 功能
使用Redis
Spring Boot 的配置如下
spring . session . store- type=Redis
spring . redis . host=127.0.0.1
spring.redis . port=6379
spring . redis.password=Redis !123
引入Redis依赖
Nginx+Redis
假设在本机上部署了两个 Spring Boot 应用 , 使用端 口分别是 9000 和 9001 。 进入工程目录, 运行 mvn package ,我们看到 ch 15. springsession\target\目录 下生成了ch17.springsession-0.0.1-SNAPSHOT.jar。然后进入命令行 , 进入 target 目录 , 启 动这个 Spring Boot 应用:
java -jar target/chl5 . springsession- 0 . 0 . !-SNAPSHOT. jar --server .port=9 000
打开另外一个命令窗口,进入工程目录 , 运行 :
java -jar target/chl5 . springsession- 0 . 0 . !-SNAPSHOT. jar --ser ver .port=90 01
这时候 , 我们就有两台 Spring Boot 应用 。 接下来,我们访 问以下地址, 并刷新多次 :
http://127.0.0.l/putsession.html
两个 Spring Boot 应用都具有相同的 sessionld,如果停掉任意一台应用, 系统还
有另外一 台服务器提供服务 , 会话信息保存在 Redis 中 。