问答平台(2),会话管理

HTTP基本性质

1
2
3
- 简单的;
- 可扩展的;
- 无状态,有会话的。

HTTP-图示

1
2
- 是服务器发送到浏览器,并存储在浏览器端的一小块数据。
- 浏览器下次访问该服务器时,会自动携带该块数据,将其发送给服务器。

Cookie工作原理-图示

表现层

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
// AlphaController.java
// cookie示例
@RequestMapping(path = "/cookie/set", method = RequestMethod.GET)
@ResponseBody
public String setCookie(HttpServletResponse response) {
// 创建cookie
Cookie cookie = new Cookie("code", CommunityUtil.generateUUID());
// 设置cookie生效的范围
cookie.setPath("/community/alpha");
// 设置cookie的生存时间(单位:秒)
cookie.setMaxAge(60 * 10);
// 发送cookie
response.addCookie(cookie);

return "set cookie";
}

@RequestMapping(path = "/cookie/get", method = RequestMethod.GET)
@ResponseBody
public String getCookie(@CookieValue("code") String code) {
System.out.println(code);
return "get cookie";
}

Cookie响应查看-图示
Cookie请求查看-图示

1
2
3
response header里有一个set-cookie,那么浏览器会按照设置的最大时间保存这个cookie,并在访问指定的路径时带上这个cookie。
使用@CookieValue注解获取cookie里某一个key-value的值。
request header里有cookie,说明浏览器发送这次请求的时候带上了cookie

Session

1
2
3
- JavaEE的标准,用于在服务器记录客户端信息。
- 数据存储在服务器更加安全,但是也会增加服务器的内存压力。
- cookie存在浏览器本地不安全,所以有session方案,session和cookie配合用。

Session工作原理-图示

表现层

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
// AlphaController.java
// Session示例
@RequestMapping(path = "/session/set", method = RequestMethod.GET)
@ResponseBody
public String setSession(HttpSession session) {
session.setAttribute("id", 1);
session.setAttribute("name", "Test");
return "set session";
}

@RequestMapping(path = "/session/get", method = RequestMethod.GET)
@ResponseBody
public String getSession(HttpSession session) {
System.out.println(session.getAttribute("id"));
System.out.println(session.getAttribute("name"));
return "get session";
}

Session响应查看-图示
Session请求查看-图示

1
2
response header里有一个set-cookie。
request header里有cookie,说明浏览器发送这次请求的时候带上了cookie

分布式部署下的 Session

1
2
3
4
- 现在网站流量都比较大,很少单服务器部署,使用session会有一些问题。所以,session使用比较少。
- 将项目部署在多台服务器上,这里涉及到nginx反向代理服务器,它会做一个负载均衡,有不同策略。
- 浏览器访问nginx,如果按照哪台服务器比较空闲就将请求分配给哪台服务器的策略,
那么创建session时可能是在服务器1,再次访问可能访问的服务器2,就无法正确的得到session

分布式部署下的Session-图示

解决方案

1
2
3
- 黏性session:固定ip分给同一个服务器处理,很难保证负载均衡。
- 同步session:当某一个服务器创建session,会将session同步给其它服务器。同步影响服务器性能;服务器产生耦合,不利于部署。
- 共享session:将session单独交给一个服务器处理。这个服务器挂了,所有服务器都无法使用,造成单点故障。

共享Session-图示

主流方法

1
2
3
尽量用cookie,敏感数据存到数据库。
传统的数据库将数据存到硬盘,访问量大的时候也会出现性能瓶颈。
所以,使用redis缓存是更好的解决方案。

补充

学完redis重构代码。


问答平台(2),会话管理
https://lcf163.github.io/2020/04/24/问答平台(2),会话管理/
作者
乘风的小站
发布于
2020年4月24日
许可协议