avatar

目录
牛客网后端项目实战(九):会话管理

TOC

  • HTTP的基本性质
    • HTTP是简单的
    • HTTP是可扩展的
    • HTTP是无状态的,有会话的
  • Cookie
    • 是服务器发送到浏览器,并保存在浏览器端的一小块数据。
    • 浏览器下次访问该服务器时,会自动携带块该数据,将其发送给服务器。
  • Session
    • 是JavaEE的标准,用于在服务端记录客户端信息。
    • 数据存放在服务端更加安全,但是也会增加服务端的内存压力。

cookie大概的流程图就是这样,我们用一个小例子来了解一下。

我们在controller里写一个设置cookie的方法。创建一个cookie对象,key-value的形式。设置它的生效范围和生存时间,默认情况下,关闭浏览器后cookie是自动失效的,设置60*10就是10分钟后失效。

java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//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 cookies";
}

访问这个路径,在浏览器中打开检查看一看。可以看到在response header里有一个set-cookie。那么浏览器就会按照我们设置的最大时间保存这个cookie,并在访问我们指定的路径时带上这个cookie。

当浏览器带上这个cookie来访问的时候,我们使用@CookieValue注解来获取cookie里某一个key-value的值。可以看到页面显示了获取到的cookie,同时在请求头里也看到了cookie,说明浏览器发送这次请求的时候带上了cookie。

java
1
2
3
4
5
@RequestMapping(path = "/alpha",method = RequestMethod.GET)
@ResponseBody
public String getCookie(@CookieValue("code") String code){
return code;
}

SESSION

由于cookie存在浏览器本地,不安全,所以有session方案,session也是和cookie一起用的。原理图如下。

session比较简单,我们只需要声明,spring容器就会自动注入,不需要我们创建。session可以存任意数据,cookie就只能存字符串。

java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
//session
@RequestMapping(path = "/session/set",method = RequestMethod.GET)
@ResponseBody
public String setSession(HttpSession session){
session.setAttribute("id",1);
session.setAttribute("name","Test");
return "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就会有一些问题。所以session使用比较少。

比如我们将项目部署在多台服务器上,这里涉及到nginx反向代理服务器,它会做一个负载均衡,有不同策略。浏览器访问nginx,如果按照哪台服务器比较空闲就将请求分配给哪台服务器的策略,那么当我创建session时可能是在服务器1,再次访问可能访问的服务器2,那么就无法正确的得到session。

这个问题解决有多种方案。

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

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

文章作者: langsam
文章链接: https://langsam1998.github.io/2020/03/13/20200313-%E7%89%9B%E5%AE%A2%E7%BD%91%E5%90%8E%E7%AB%AF%E9%A1%B9%E7%9B%AE%E5%AE%9E%E6%88%98%EF%BC%88%E4%B9%9D%EF%BC%89%EF%BC%9A%E4%BC%9A%E8%AF%9D%E7%AE%A1%E7%90%86/
版权声明: 本博客所有文章除特别声明外,均采用 CC BY-NC-SA 4.0 许可协议。转载请注明来自 平儿的博客
打赏
  • 微信
    微信
  • 支付寶
    支付寶

评论