1 为何需要Session共享?
因为每个应用容器默认是将Session存储在本地内存,仅容器本身可以访问,但是在分布式集群中,包含多个应用容器,一个用户请求会随机发送到容器上,比如,用户在A容器登陆,登陆后又访问B容器,那咋办呢?方案就是:Session共享。
2 方案样例:springboot + redis
安装redis可参考:https://blog.csdn.net/qqchaozai/article/details/100119944
springboot环境搭建可参考:https://blog.csdn.net/qqchaozai/article/details/82355175
- 先在pom.xml中引入依赖库
<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.2.RELEASE</version>
</parent>
<groupId>com.web.spring</groupId>
<artifactId>cluster2</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>jar</packaging>
<name>cluster</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!-- web -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- redis -->
<!-- https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-data-redis -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-data-redis</artifactId>
</dependency>
<!-- Spring session -->
<dependency>
<groupId>org.springframework.session</groupId>
<artifactId>spring-session-data-redis</artifactId>
</dependency>
</dependencies>
</project>
- application.properties配置redis
#####################server######################
server.port=8000
server.tomcat.uriEncoding=utf-8
#####################redis######################
redis.database=local
redis.host=127.0.0.1
redis.password=
redis.port=6379
- 启动类+测试Controller
@SpringBootApplication
@EnableRedisHttpSession
public class App
{
public static void main( String[] args )
{
SpringApplication.run(App.class, args);
}
}
/**
* 用于测试共享Session数据访问
*
* @author chaozai
* @date 2019年8月28日
*
*/
@RestController
public class SessionController {
/**
* 登陆时,将当前登陆IP记录到session中
*
* @param request
* @return
*/
@GetMapping("/login")
public Map<String, Object> setUrl(HttpServletRequest request) {
request.getSession().setAttribute("address", request.getRemoteAddr());
Map<String, Object> map = new HashMap<>();
map.put("address", request.getRemoteAddr());
return map;
}
/**
* 获取当前session内容
*
* @param request
* @return
*/
@GetMapping("/getSession")
public Map<String, Object> getSession(HttpServletRequest request) {
Map<String, Object> map = new HashMap<>();
map.put("sessionId", request.getSession().getId());
map.put("address", request.getSession().getAttribute("address"));
return map;
}
}
负责一份工程,重命名,修改新端口号为8001,启动两个工程,测试:
- 8000服务登陆:返回当前访问IP为127.0.0.1
- 8000服务访问Session:返回当前Session内容
- 8001服务不登陆直接访问Session:返回Session内容和8000服务一毛一样
- 去redis里确认下,session相关数据是否都存了:没毛病
3 原理浅析
未完待续......
爱家人,爱生活,爱设计,爱编程,拥抱精彩人生!