在集群项目中,实现 Session 共享的方案
使用 Spring Session 来实现这一功能,Spring Session 就是使用 Spring 中的代理过滤器,将所有的 Session 操作拦截下来,自动的将数据 同步到 Redis 中,或者自动的从 Redis 中读取数据。
对于开发者来说,所有关于 Session 同步的操作都是透明的,开发者使用 Spring Session,一旦配置完成后,具体的用法就像使用一个普通的 Session 一样。
boot版本 2.0.6
nginx
redis
新建Boot项目
pom.xml
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!--redis 配置-->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!--redis session 共享-->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
application.yml
server:
port: 13002
servlet:
context-path: /projecsession
spring:
session:
store-type: redis #session的存储方式
redis:
host: 127.0.0.1
port: 6379
password: redis
简单代码
@GetMapping("/login")
public String login(HttpServletRequest request, String name) {
request.getSession().setAttribute(name, request.getSession().getId());
return "这是13001端口 :" + request.getSession().getId();
}
@GetMapping("/getSession")
public String getSession(HttpServletRequest request,String name) {
return "这是13001端口 :"+ request.getSession().getAttribute(name);
}
新建一个项目(代码相同,只是端口不一样 13002)
将2个项目打成jar包并发布
启动脚本
#!/bin/bash
server_name=`ls *.jar`
echo $server_name
java -server -jar ./$server_name >> ${server_name}.out 2>&1 &
配置Nginx
修改 nginx.conf文件 并重新启动 ./nginx -s reload
# 配置集群 backServer 集群名字 随意定义 weight 分配权重
upstream backServer {
server 127.0.0.1:13001 weight=1;
server 127.0.0.1:13002 weight=1;
}
server {
listen 80;
server_name test.yu.com;
#charset koi8-r;
#access_log logs/host.access.log main;
location ^~/projecsession {
proxy_pass http://backServer;
proxy_set_header Host $host;
# 此配置使得服务端可以获取客户端真实ip
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme;
upstream 表示配置上游服务器
backServer 表示服务器集群的名字,这个可以随意取名字
upstream 里边配置的是一个个的单独服务
weight 表示服务的权重,意味者将有多少比例的请求从 Nginx 上转发到该服务上
location 中的 proxy_pass 表示请求转发的地址,/ 表示拦截到所有的请求,转发转发到刚刚配置好的服务集群中
语法形式
location [ = | ~ | ~* | ^~ | @] /uri/ { configuration }
匹配模式及顺序
匹配字符串分为两种:普通字符串(literal string)和正则表达式(regular expression),其中 ~ 和 ~* 用于正则表达式, 其他前缀和无任何前缀都用于普通字符串。
匹配顺序是:1、先匹配普通字符串,将最精确的匹配暂时存储;2、然后按照配置文件中的声明顺序进行正则表达式匹配,只要匹配到一条正则表达式,则停止匹配,取正则表达式为匹配结果;3、如果所有正则表达式都匹配不上,则取1中存储的结果;4、如果普通字符串和正则表达式都匹配不上,则报404 NOT FOUND。
location = /uri =开头表示精确前缀匹配,只有完全匹配才能生效。
location ^~ /uri ^~开头表示普通字符串匹配上以后不再进行正则匹配。
location ~ pattern ~开头表示区分大小写的正则匹配。
location ~* pattern ~*开头表示不区分大小写的正则匹配。
location /uri 不带任何修饰符,表示前缀匹配。
location / 通用匹配,任何未匹配到其他location的请求都会匹配到。
注意:正则匹配会根据匹配顺序,找到第一个匹配的正则表达式后将停止搜索。普通字符串匹配则无视顺序,只会选择最精确的匹配。
测试
页面可见 Seesion共享实现了,看一下Redis的数据