1、SpringSession简介
是SpringCloud下管理session的框架,在微服务架构中,由于应用了分布式的思想,session无法做到内存中互通,需要一个框架来实现各个微服务中session数据共享,SpringSession解决了这个问题。
在SpringSession框架中,可以无感的实现和操作session共享。
2、实现session共享的三种方式
1、修改Tomcat配置文件
可以通过修改配置文件实现session共享,现在已经不用这种方式了,有很多限制。
2、Nginx负载均衡策略
通过ip_hash的方式,让同一个ip的请求到相同的服务中,session自然没有失效。这种方式也不推荐,无法做到效率及硬件利用率最高的负载均衡。
upstream server{
ip_hash;
server 192.168.1.101:28080 max_fails=1 fail_timeout=60s weight=1;
server 192.168.1.101:28090 max_fails=1 fail_timeout=60s weight=2;
}server {
listen 80;
server_name 192.168.1.115;location / {
proxy_pass server
}
}
3、redis统一存储
SpringBoot整合SpringSession,通过nacos进行配置管理,通过redis存储方式实现session共享
官网文档:Spring Session - Spring Boot
0、准备工作
【1.启动redis,nacos】
【2.准备两个项目应用,编写两份一样的代码】
【2.1添加pom.xml依赖】
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.7.RELEASE</version>
</parent>
<properties>
<java.version>1.8</java.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<spring-boot.version>2.6.13</spring-boot.version>
<jwt.version>0.7.0</jwt.version>
<fastjson.version>1.2.60</fastjson.version>
<spring-cloud-alibaba.version>2.0.3.RELEASE</spring-cloud-alibaba.version>
<spring-cloud.version>Finchley.SR2</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
<!--json-->
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>fastjson</artifactId>
<version>${fastjson.version}</version>
<scope>compile</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>${spring-cloud-alibaba.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<classifier>exec</classifier>
</configuration>
</plugin>
</plugins>
</build>
【2.2添加修改项目控制器】
import lombok.Setter;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.servlet.http.HttpSession;
@RestController
@RequestMapping("/user")
@Setter
public class UserController {
@GetMapping
public String test(HttpSession session){
return session.getId();
}
}
【2.3修改项目端口号】
【这里只取一个就可以】后面还会新建一个项目
#在application.yml文件里:
server:
port: 67
------------------------
server:
port: 68
【2.4创建启动类】
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class SpringBootMain {
public static void main(String[] args) {
SpringApplication.run(SpringBootMain.class);
}
}
【2.5启动,访问两个项目】
=====此时,两个项目的sessionID不一致。
1、本地服务添加依赖
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId>
</dependency>
2、修改本地服务配置文件
spring:
session:
store-type: redis
3、添加application.properties文件
spring.application.name=sessiondemo
4、添加nacos - redis配置
详细流程可观看如下链接 3.配置中心 下的【5、创建命名空间】
微服务nacos解析部署使用全流程
登录此网址http://192.168.146.128:8848/nacos/#/login 用自己的ip
5、修改本地项目bootstrap.yml文件
#server-addr: 192.168.146.128:8848 端口号和虚拟机端口
spring:
cloud:
nacos:
discovery:
server-addr: 192.168.146.128:8848
config:
server-addr: 192.168.146.128:8848
file-extension: yaml
namespace: e3b50403-a164-48e3-b6d3-d060277c1e62
shared-configs:
- data-id: session.yaml
group: DEFAULT_GROUP
inetutils:
preferred-networks: 192.168.146
两个项目的bootstrap.yml文件相同
【注意这张图时告诉每个位置放什么】 图片并非本项目
server-addr:nacos服务ip及端口
file-extension:配置文件类型
namespace:命名空间,在nacos页面中创建,用来管理配置文件
shared-configs:配置中心配置
data-id:配置文件唯一标识
group:配置文件分组
preferred-networks:设置微服务的网段
6、开启SpringSession
@EnableRedisHttpSession
7、子域名共享session
需要创建一个config目录,新建SessionConfig配置类,修改domain作用域
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import org.springframework.session.web.http.CookieSerializer;
import org.springframework.session.web.http.DefaultCookieSerializer;
/**
* @author szsw
* @date 2023/2/16 19:22:06
*/
@Configuration
public class SessionConfig {
@Bean
public CookieSerializer cookieSerializer() {
DefaultCookieSerializer serializer = new DefaultCookieSerializer();
serializer.setCookieName("JSESSIONID");
serializer.setCookiePath("/");
serializer.setDomainNamePattern("^.+?\\.(\\w+\\.[a-z]+)$");
return serializer;
}
@Bean
public RedisSerializer<Object> redisSerializer() {
return new GenericJackson2JsonRedisSerializer();
}
}
8、测试
重启一下两个服务,之后访问一下nacos。
两个id相同实现共享