首页 > 其他分享 >ThreadLocal 存储用户信息

ThreadLocal 存储用户信息

时间:2024-09-12 17:25:20浏览次数:12  
标签:存储 存储用户 信息 ThreadLocal Session Cookie 服务器 客户端

1 Cookie + Session

由于 HTTP 协议是无状态的,完成操作关闭浏览器后,客户端和服务端的连接就断开了,所以我们必须要有一种机制来保证客户端和服务端之间会话的连续性,常见的,就是使用Cookie + Session (会话) 的方式。

具体来说,当客户端请求服务端的时候,服务端会为此次请求开辟一块内存空间(Session 对象),服务端可以在此存储客户端在该会话期间的一些操作记录(比如用户信息就可以存在 Session 中),同时会生成一个 sessionID ,并通过响应头的Set-Cookie:JSESSIONID=XXXXXXX命令,将 seesionID 存储进客户端的 Cookie 中。

可能会有同学问为啥不直接把数据全部存在 Cookie 中,还整个 Session 出来然后把 sessionID 存在 Cookie 中的?

  • Cookie 长度的限制 :首先,最基本的,Cookie 是有长度限制的,这限制了它能存储的数据的长度
  • 性能影响 :Cookie 确实和 Session 一样可以让服务端程序跟踪每个客户端的访问,但是每次客户端的访问都必须传回这些 Cookie,那如果 Cookie 中存储的数据比较多的话,这无疑增加了客户端与服务端之间的数据传输量,增加了服务器的压力。
  • 安全性 :Session 数据其实是属于服务端的数据,而 Cookie 属于客户端,把本应在 Session 中存储的数据放到客户端 Cookie,使得服务端数据延伸到了外部网络及客户端,显然是存在安全性上的问题的。当然我们可以对这些数据做加密,不过从技术来讲物理上不接触才是最安全的。

这样,按照 Cookie + Seesion 的机制,服务端在接到客户端请求的时候,只要去 Cookie 中获取到 sessionID 就能据此拿到 Session 了。Session 存活期间,我们认为客户端一直处于活跃状态(用户处于登录态),一旦 Session 超期过时,那么就可以认为客户端已经停止和服务器进行交互了(用户退出登录)。


如果遇到禁用 Cookie 的情况,一般的做法就是把这个 sessionID 放到 URL 参数中。这也是经常在面试中会被问到的问题。

这种机制在单体应用时代应用非常广泛,但是,随着分布式时代的到来,Session 的缺点也逐渐暴露出来。

举个例子,比如我们有多个服务器,客户端 1 向服务器发送了一个请求,由于负载均衡的存在,该请求被转发给了服务器 A,于是服务器 A 创建并存储了这个 Session

ThreadLocal 存储用户信息_服务器

图片

紧接着,客户端 1 又向服务器发送了一个请求,但是这一次请求被负载均衡给了服务器 B,而服务器 B 这时候是没有存储服务器 A 的 Session 的,这就导致 Session 的失效。

ThreadLocal 存储用户信息_数据_02

图片

明明用户在上一个界面还是登录的,跳到下一个界面就退出登录了,这显然不合理。

2 分布式集群 Session 共享

当然了,对此的解决方法其实也有很多种,其实就是如何解决 Session 在多个服务器之间的共享问题:

Session Replication

这个是最容易想到的,既然服务器 B 没有服务器 A 存储的 Session,那各个服务器之间同步一下 Session 数据不就完了。

ThreadLocal 存储用户信息_服务器_03

图片

这种方案存在的问题也是显而易见的:

  • 同步 Session 数据带来了额外的网络带宽开销。只要 Session 数据有变化,就需要将数据同步到所有其他机器上,机器越多,同步带来的网络带宽开销就越大。
  • 每台Web服务器都要保存所有 Session 数据,如果整个集群的 Session 数据很多(比如很多人同时访问网站的情况),每台服务器用于保存 Session 数据的内存占用会非常严重。

Session Sticky

从名称也能看出来,Sticky,即让负载均衡器能够根据每次的请求的会话标识来进行请求的转发,保证一个会话中的每次请求都能落到同一台服务器上面。

ThreadLocal 存储用户信息_数据_04

图片

存在问题的:

  • 如果某台服务器宕机或者重启了,那么它上面存储的 Session 数据就丢失了,用户就需要重新进行登陆。
  • 负载均衡器变为一个有状态的节点,因为他需要保存 Session 到具体服务器的映射,和之前无状态的节点相比,内存消耗会更大,容灾方面会更麻烦。

Session 数据集中存储

借助外部存储(Redis、MySQL 等),将 Session 数据进行集中存储,然后所有的服务器都从这个外部存储中拿 Session

ThreadLocal 存储用户信息_服务器_05

图片

存在的问题也很显然:

  • 过度依赖外部存储,如果集中存储 Session 的外部存储机器出问题了,就会直接影响到我们的应用

3 ThreadLocal

事实上,无论采用何种方案,使用 Session 机制,会使得服务器集群很难扩展,因此,Session 适用于中小型 Web 应用程序。对于大型 Web 应用程序来说,通常需要避免使用 Session 机制。

So,在 Echo 项目中,我们决定摒弃 Session,一个 ThreadLocal 解决所有问题(狗头)!

ThreadLocal 线程本地内存,很好理解,就是每个访问 ThreadLocal 变量的线程都有自己的一个 “本地” 实例副本,每个线程之间互相隔离,互不干涉。

这里我就不详细解释底层原理了,ThreadLocal 适用于如下两种场景:

  • 每个线程需要有自己单独的实例(数据)
  • 实例(数据)需要在多个方法中共享,但不希望被多线程共享

来看如何用 ThreadLocal 实现我们的需求:显示登录信息,在本次请求中持有当前用户数据。

首先我们需要明白的是,ThreadLocal 只跟其归属的线程有关,线程死亡了,那么它对应的 ThreadLocal 中存储的信息也就被清除了(线程死亡前一定要释放掉绑定的用户数据,不然会出现 OOM 问题),也就是说,ThreadLocal 只用于在本次请求中持有数据。

简单来说,我们把用户数据存入 ThreadLocal 里,这样,只要本次请求未处理完,这个线程就一直还在,当前用户数据就一直被持有,当服务器对本次请求做出响应后,这个线程就会被销毁。

那同一个用户发出的两次请求可能被不同的两个线程进行处理,如何使得这个两个线程的 ThreadLocal 持有相同的用户信息呢?

过滤器。

具体来说,我们定义一个过滤器,在每次请求前都对用户进行判断(为了避免每次请求都经过过滤器,可以将登录成功的用户信息暂时存储到 Redis 中),然后将已经登录成功的用户信息存到 ThreadLocal 里,从而使得该线程在本次请求中持有该用户信息。

标签:存储,存储用户,信息,ThreadLocal,Session,Cookie,服务器,客户端
From: https://blog.51cto.com/maguobin/11992223

相关文章

  • Metacritic 网站中的游戏开发者和类型信息爬取
    为了从Metacritic网站上爬取游戏的开发者和类型信息,你可以使用Python的网络爬虫工具,比如requests和BeautifulSoup,或者更高级的工具如Scrapy或Selenium。本文将介绍一种基于requests和BeautifulSoup的简单爬虫示例,并假设目标是从Metacritic的单个游戏页面上提取开发......
  • PHP体检信息管理系统-计算机毕业设计源码54850
    目录1绪论1.1选题背景1.2选题意义1.3研究的主要内容1.4论文结构与章节安排2系统分析2.1.1技术可行性分析2.1.2经济可行性分析2.1.3操作可行性分析2.2系统流程分析2.2.1数据新增流程2.2.2 数据删除流程2.3 系统功能分析2.3.1功能性分析2.......
  • 第七章习题3-写一个判断素数的函数,在主函数中输入一个整数,输出是否为素数的信息
     ......
  • 如何获取并展示PDD商品的详细信息?
    PDD作为国内的一家知名电商平台,拥有着庞大的商品数量和用户数量。对于开发者们来说,如何快速高效地获取并展示PDD平台上的商品详情就成了一项必要的技术工作。本文将介绍PDD商品详情的获取以及应用。一、商品详情的获取通过使用提供的API接口,可以轻松地获取到平台上任意商品......
  • 基于springboot+vue的师生健康信息管理系统(源码+数据库+文档)
    师生健康信息|师生健康信息管理系统目录基于springboot+vue的师生健康信息管理系统一、前言二、系统设计三、系统功能设计 四、数据库设计 五、核心代码 六、论文参考七、最新计算机毕设选题推荐八、源码获取:博主介绍:✌️大厂码农|毕设布道师,阿里云开发社区乘风......
  • 用 Rust 实现敏感信息拦截插件,提升 AI 网关安全防护能力
    作者:刘毅杰,棱镜七彩信息科技有限公司研发,HigressMember前言AI时代内容安全的重要性随着大模型技术的发展,企业越来越依赖这些模型来进行业务处理。然而,数据安全成为了不容忽视的问题。主要有两方面的隐患:AI生成内容的不可控性:LLM的回答可能产生涉黄、涉暴等内容,为业务和......
  • 基于django+vue车站商铺信息管理系统【开题报告+程序+论文】-计算机毕设
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着城市化进程的加速和公共交通网络的不断完善,大型车站作为城市的重要交通枢纽,其周边商业活动日益繁荣。车站商铺作为旅客服务的重要组成......
  • 《数字图像处理(面向新工科的电工电子信息基础课程系列教材)》Chapter 1课件2024
    每一轮备课都有新的感悟。禹晶、肖创柏、廖庆敏《数字图像处理(面向新工科的电工电子信息基础课程系列教材)》禹晶、肖创柏、廖庆敏《数字图像处理》资源二维码......
  • ThreadLocal源码分析-
    ThreadLocal源码分析ThreadLocal是解决线程安全问题的一种方法,它通过为每个线程提供一个独立的变量副本避免了变量并发访问的冲突问题。一个ThreadLocal变量只与当前自身线程相关,对其他线程是隔离的。下面这段代码展示了ThreadLocal的使用。publicclasstest{privatesta......
  • [开题报告]flask框架基于web的毕业生就业信息管理系统eua8u(python+程序+论文)
    本系统(程序+源码+数据库+调试部署+开发环境)带论文文档1万字以上,文末可获取,系统界面在最后面。系统程序文件列表开题报告内容研究背景随着高等教育的普及与毕业生数量的逐年增加,毕业生就业问题成为社会关注的焦点。传统的就业信息获取与管理方式已难以满足当前高效、精准的......