聊聊分布式会话及实现方案

鲁大猿,寻找精品资料,帮你构建Java全栈知识体系 http://www.jiagoujishu.cn

基础概念

Session + Cookie 会话方案比较简单,这里我在网上找了点资料,再回顾下基础吧。

为什么要产生Session

http协议本身是无状态的,客户端只需要向服务器请求下载内容,客户端和服务器都不记录彼此的历史信息,每一次请求都是独立的。

为什么是无状态的呢?因为浏览器与服务器是使用socke套接字进行通信,服务器将请求结果返回给浏览器之后,会关闭当前的socket链接,而且服务器也会在处理页面完毕之后销毁页面对象。

然而在Web应用的很多场景下需要维护用户状态才能正常工作(是否登录等),或者说提供便捷(记住密码,浏览历史等),状态的保持就是一个很重要的功能。因此在web应用开发里就出现了保持http链接状态的技术:一个是cookie技术,另一种是session技术。

Session有什么作用,如何产生并发挥作用

要明白Session就必须要弄明白什么是Cookie,以及Cookie和Session的关系。

  • 什么是Cookie

Cookie技术是http状态保持在客户端的解决方案,Cookie就是由服务器发给客户端的特殊信息,而这些信息以文本文件的方式存放在客户端,然后客户端每次向服务器发送请求的时候都会带上这些特殊的信息。

  • Cookie的产生

当用户首次使用浏览器访问一个支持Cookie的网站的时候,用户会提供包括用户名在内的个人信息并且提交至服务器;接着,服务器在向客户端回传相应的超文本的同时也会发回这些个人信息,当然这些信息并不是存放在HTTP响应体(Response Body)中的,而是存放于HTTP响应头(Response Header);当客户端浏览器接收到来自服务器的响应之后,浏览器会将这些信息存放在一个统一的位置。

存储在硬盘上的cookie 不可以在不同的浏览器间共享,可以在同一浏览器的不同进程间共享,比如两个IE窗口。这是因为每中浏览器存储cookie的位置不一样,比如

  • Chrome下的cookie放在:C:\Users\sharexie\AppData\Local\Google\Chrome\User Data\Default\Cache
  • Firefox下的cookie放在:C:\Users\sharexie\AppData\Roaming\Mozilla\Firefox\Profiles\tq2hit6m.default\cookies.sqlite (倒数第二个文件名是随机的文件名字)
  • Ie下的cookie放在:C:\Users\Administrator\AppData\Roaming\Microsoft\Windows\Cookies
  • Cookie的内容、作用域以及有效期

cookie的内容主要包括:名字,值,过期时间,路径和域。路径与域合在一起就构成了cookie的作用范围。

如果不设置过期时间,则表示这个cookie的生命期为浏览器会话期间,只要关闭浏览器窗口,cookie就消失了,这种生命期为浏览器会话期的 cookie被称为会话cookie。会话cookie一般不存储在硬盘上而是保存在内存里。如果设置了过期时间,浏览器就会把cookie保存到硬盘上,关闭后再次打开浏览器,这些cookie仍然有效直到超过设定的过期时间。

  • Cookie如何使用

cookie 的使用是由浏览器按照一定的原则在后台自动发送给服务器的。

当客户端二次向服务器发送请求的时候,浏览器检查所有存储的cookie,如果某个cookie所声明的作用范围大于等于将要请求的资源所在的位置,则把该cookie附在请求资源的HTTP请求头上发送给服务器。有了Cookie这样的技术实现,服务器在接收到来自客户端浏览器的请求之后,就能够通过分析存放于请求头的Cookie得到客户端特有的信息,从而动态生成与该客户端相对应的内容。通常,我们可以从很多网站的登录界面中看到“请记住我”这样的选项,如果你勾选了它之后再登录,那么在下一次访问该网站的时候就不需要进行重复而繁琐的登录动作了,而这个功能就是通过Cookie实现的。

  • 什么是Session

Session一般叫做会话,Session技术是http状态保持在服务端的解决方案,它是通过服务器来保持状态的。我们可以把客户端浏览器与服务器之间一系列交互的动作称为一个 Session。是服务器端为客户端所开辟的存储空间,在其中保存的信息就是用于保持状态。因此,session是解决http协议无状态问题的服务端解决方案,它能让客户端和服务端一系列交互动作变成一个完整的事务。

  • Session的创建

那么Session在何时创建呢?当然还是在服务器端程序运行的过程中创建的,不同语言实现的应用程序有不同创建Session的方法。

当客户端第一次请求服务端,当server端程序调用 HttpServletRequest.getSession(true)这样的语句时的时候,服务器会为客户端创建一个session,并将通过特殊算法算出一个session的ID,用来标识该session对象。

Session存储在服务器的内存中(tomcat服务器通过StandardManager类将session存储在内存中),也可以持久化到file,数据库,memcache,redis等。客户端只保存sessionid到cookie中,而不会保存session。

浏览器的关闭并不会导致Session的删除,只有当超时、程序调用HttpSession.invalidate()以及服务端程序关闭才会删除。

  • Tomcat中的Session创建

ManagerBase是所有session管理工具类的基类,它是一个抽象类,所有具体实现session管理功能的类都要继承这个类,该类有一个受保护的方法,该方法就是创建sessionId值的方法:

(tomcat的session的id值生成的机制是一个随机数加时间加上jvm的id值,jvm的id值会根据服务器的硬件信息计算得来,因此不同jvm的id值都是唯一的)。

StandardManager类是tomcat容器里默认的session管理实现类,它会将session的信息存储到web容器所在服务器的内存里。 PersistentManagerBase也是继承ManagerBase类,它是所有持久化存储session信息的基类,PersistentManager继承了PersistentManagerBase,但是这个类只是多了一个静态变量和一个getName方法,目前看来意义不大,对于持久化存储session,tomcat还提供了StoreBase的抽象类,它是所有持久化存储session的基类,另外tomcat还给出了文件存储FileStore和数据存储JDBCStore两个实现。

  • Cookie与Session的关系

cookie和session的方案虽然分别属于客户端和服务端,但是服务端的session的实现对客户端的cookie有依赖关系的,服务端执行session机制时候会生成session的id值,这个id值会发送给客户端,客户端每次请求都会把这个id值放到http请求的头部发送给服务端,而这个id值在客户端会保存下来,保存的容器就是cookie,因此当我们完全禁掉浏览器的cookie的时候,服务端的session也会不能正常使用。

会话技术的发展

会话技术的发展?

  • 单机 - Session + Cookie

  • 多机器

    • 在负载均衡侧 - Session 粘滞
    • Session数据同步
  • 多机器,集群 - session集中管理,比如redis;目前方案上用的最多的是SpringSession,早前也有用tomcat集成方式的。

  • 无状态token,比如JWT

分布式会话的方案

无状态的token或者有状态的Session集中管理是目前最为常用的方案, 本节主要讨论的有状态的分布式Session会话。

Session Stick

为什么这种方案到目前还有很多项目使用呢?因为不需要在项目代码侧改动,而是只需要在负载均衡侧改动。

方案即将客户端的每次请求都转发至同一台服务器,这就需要负载均衡器能够根据每次请求的会话标识(SessionId)来进行请求转发,如下图所示。

image.png

这种方案实现比较简单,对于Web服务器来说和单机的情况一样。但是可能会带来如下问题:

  • 如果有一台服务器宕机或者重启,那么这台机器上的会话数据会全部丢失。
  • 会话标识是应用层信息,那么负载均衡要将同一个会话的请求都保存到同一个Web服务器上的话,就需要进行应用层(第7层)的解析,这个开销比第4层大。
  • 负载均衡器将变成一个有状态的节点,要将会话保存到具体Web服务器的映射。和无状态节点相比,内存消耗更大,容灾方面也会更麻烦。

Session Replication

Session Replication 的方案则不对负载均衡器做更改,而是在Web服务器之间增加了会话数据同步的功能,各个服务器之间通过同步保证不同Web服务器之间的Session数据的一致性,如下图所示。

image.png

Session Replication 方案对负载均衡器不再有要求,但是同样会带来以下问题:

  • 同步Session数据会造成额外的网络带宽的开销,只要Session数据有变化,就需要将新产生的Session数据同步到其他服务器上,服务器数量越多,同步带来的网络带宽开销也就越大。
  • 每台Web服务器都需要保存全部的Session数据,如果整个集群的Session数量太多的话,则对于每台机器用于保存Session数据的占用会很严重。

Session 数据集中存储

Session 数据集中存储方案则是将集群中的所有Session集中存储起来,Web服务器本身则并不存储Session数据,不同的Web服务器从同样的地方来获取Session,如下图所示。

image.png

相对于Session Replication方案,此方案的Session数据将不保存在本机,并且Web服务器之间也没有了Session数据的复制,但是该方案存在的问题在于:

  • 读写Session数据引入了网络操作,这相对于本机的数据读取来说,问题就在于存在时延和不稳定性,但是通信发生在内网,则问题不大。
  • 如果集中存储Session的机器或集群出现问题,则会影响应用。

Cookie Based

Cookie Based 方案是将Session数据放在Cookie里,访问Web服务器的时候,再由Web服务器生成对应的Session数据,如下图所示。

image.png

但是Cookie Based 方案依然存在不足:

  • Cookie长度的限制。这会导致Session长度的限制。
  • 安全性。Seesion数据本来是服务端数据,却被保存在了客户端,即使可以加密,但是依然存在不安全性。
  • 带宽消耗。这里不是指内部Web服务器之间的宽带消耗,而是数据中心的整体外部带宽的消耗。
  • 性能影响。每次HTTP请求和响应都带有Seesion数据,对Web服务器来说,在同样的处理情况下,响应的结果输出越少,支持的并发就会越高。

Token

JSON Web Token,一般用它来替换掉Session实现数据共享。

使用基于 Token 的身份验证方法,在服务端不需要存储用户的登录记录。大概的流程是这样的:

  • 1、客户端通过用户名和密码登录服务器;
  • 2、服务端对客户端身份进行验证;
  • 3、服务端对该用户生成Token,返回给客户端;
  • 4、客户端将Token保存到本地浏览器,一般保存到cookie中;
  • 5、客户端发起请求,需要携带该Token;
  • 6、服务端收到请求后,首先验证Token,之后返回数据。

image.png

如上图为Token实现方式,浏览器第一次访问服务器,根据传过来的唯一标识userId,服务端会通过一些算法,如常用的HMAC-SHA256算法,然后加一个密钥,生成一个token,然后通过BASE64编码一下之后将这个token发送给客户端;客户端将token保存起来,下次请求时,带着token,服务器收到请求后,然后会用相同的算法和密钥去验证token,如果通过,执行业务操作,不通过,返回不通过信息。

可以对比下图session实现方式,流程大致一致。

image.png

优点

  • 无状态、可扩展 :在客户端存储的Token是无状态的,并且能够被扩展。基于这种无状态和不存储Session信息,负载均衡器能够将用户信息从一个服务传到其他服务器上。
  • 安全:请求中发送token而不再是发送cookie能够防止CSRF(跨站请求伪造)。
  • 可提供接口给第三方服务:使用token时,可以提供可选的权限给第三方应用程序。
  • 多平台跨域

对应用程序和服务进行扩展的时候,需要介入各种各种的设备和应用程序。 假如我们的后端api服务器a.com只提供数据,而静态资源则存放在cdn 服务器b.com上。当我们从a.com请求b.com下面的资源时,由于触发浏览器的同源策略限制而被阻止。

我们通过CORS(跨域资源共享)标准和token来解决资源共享和安全问题

举个例子,我们可以设置b.com的响应首部字段为:

// 第一行指定了允许访问该资源的外域 URI。
Access-Control-Allow-Origin: http://a.com
​
// 第二行指明了实际请求中允许携带的首部字段,这里加入了Authorization,用来存放token。
Access-Control-Allow-Headers: Authorization, X-Requested-With, Content-Type, Accept
​
// 第三行用于预检请求的响应。其指明了实际请求所允许使用的 HTTP 方法。
Access-Control-Allow-Methods: GET, POST, PUT,DELETE
​
// 然后用户从a.com携带有一个通过了验证的token访问B域名,数据和资源就能够在任何域上被请求到。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mfbz.cn/a/289821.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

《绝地求生》改名卡快速获得方法 绝地求生改名卡怎么获得

《绝地求生》改名卡是很多小伙伴所在意的物品,购买通行证后需要提升一定的等级才能入手,而怎么升级最快最划算呢?今天闲游盒带来“米奇”分享的《绝地求生》改名卡快速获得方法,赶紧来试试吧。 吃鸡刚刚迎来了更新,通行…

八大算法排序@冒泡排序(C语言版本)

冒泡排序 概念 冒泡排序(Bubble Sort)是一种简单直观的排序算法,它重复地遍历待排序序列,一次比较两个相邻的元素,如果它们的顺序错误就将它们交换过来。通过多次的遍历,使得最大的元素逐渐移动到待排序序…

Windows—常用DOS命令

解释:DOS命令即面向磁盘的操作命令 进入DOS页面:快捷键“winR”,输入cmd help命令 help 【命令名】可查看其他命令的解释,直接输入help也可以查看部分命令 另外,如果输入help显示help不是内部或外部命令,…

ACCESS从零入门教程

最近,在公司实习自学了一款简单的access数据库软件,下面是自己的一些学习心得过程,供大家参考。 一、access导入数据 两种方法: 1、直接复制,crtl-c/v即可 2、若数据量较大,可以从access内部进行导入&am…

c++语言基础18-开房门

题目描述 假设你手里有一串钥匙,这串钥匙上每把钥匙都有一个编号,对应着一个房门的编号。现给你一个房门编号,你需要判断是否能够打开该房门。 输入描述 测试数据共有多组。 第一行为一个整数 s,表示共有多少组测试数据。 每组第一…

c# OpenCvSharp透视矫正参数调整器

透视矫正不够智能化,每次都要进行局部参数调整,不便于程序使用,程序流程还是那几个步骤; 1、读取图像、灰度化 2、高斯滤波 3、二值化 4、边缘检测 灰度化图 上个图看看经过调整透视矫正边缘检测结果我还是挺满意的 发现一个…

基于springboot智慧食堂管理系统源码和论文

随着Internet的发展,人们的日常生活已经离不开网络。未来人们的生活与工作将变得越来越数字化,网络化和电子化。网上管理,它将是直接管理“智慧食堂”系统的最新形式。本论文是以构建“智慧食堂”系统为目标,使用java技术制作&…

Java Synchronized 和 ReentrantLock

目录 介绍 synchronized synchronized 修饰实例方法 修饰静态类方法 synchronized 修饰代码块 实现细节 ReentrantLock ReentrantLock 基本使用 公平锁实现 读写锁(ReentrantReadWriteLock) 1. 创建读写锁对象: 2. 通过读写锁对象…

IDS 和 IPS:了解异同

IDS 和 IPS 是至关重要的网络安全技术,经常被混淆或互换使用。那么,IDS 和 IPS 之间有什么区别,哪一种是最适合您组织需求的选择呢? 什么是IDS(入侵检测系统)? 入侵检测系统 (IDS) 是一种网络…

【管理篇 / 登录】❀ 06. macOS下使用USB配置线登录 ❀ FortiGate 防火墙

【简介】飞塔防火墙上都会配有CONSOLE接口,包装里都会配置一根USB配置线,通过这个接口和这根线,我们可以用命令的方式登录飞塔防火墙进行操作。随着苹果电脑的普及,我们来学习一下,如果在MAC OS中用配置线登录飞塔防火…

【零基础入门TypeScript】判断条件和循环

目录 定环 无限循环 示例:while 与 do..while 中断语句 句法 流程图 例子 继续语句 句法 流程图 例子 输出 无限循环 语法:使用 for 循环的无限循环 示例:使用 for 循环的无限循环 语法:使用 while 循环进行无限循…

pytorch06:权重初始化

目录 一、梯度消失和梯度爆炸1.1相关概念1.2 代码实现1.3 实验结果1.4 方差计算1.5 标准差计算1.6 控制网络层输出标准差为11.7 带有激活函数的权重初始化 二、Xavier方法与Kaiming方法2.1 Xavier初始化2.2 Kaiming初始化2.3 常见的初始化方法 三、nn.init.calculate_gain 一、…

程序媛的mac修炼手册--MacOS系统更新升级史

啊,我这个口罩三年从未感染过新冠的天选免疫王,却被支原体击倒😷大意了,前几天去医院体检,刚检查完出医院就摘口罩了🤦大伙儿还是要注意戴口罩,保重身体啊!身体欠恙,就闲…

Excel 插件:ASAP Utilities Crack

ASAP Utilities是一款功能强大的 Excel 插件,填补了 Excel 的空白。在过去的 20 年里,我们的加载项已经发展成为世界上最受欢迎的 Microsoft Excel 加载项之一。 ASAP Utilities 中的功能数量(300 多个)可能看起来有点令人眼花缭乱…

Navicat 技术干货 | 聚合查询的介绍

基础 SQL 查询可以检索、插入、更新和删除记录,而聚合查询可通过提供求和、平均值或最大/最小值等的大型结果集,将数据库交互提升到一个新的水平。本文中,我们将探索聚合 SQL 查询的基础知识,并研究如何有效的利用他们来分析和汇总…

Unity中URP下的线性雾

文章目录 前言一、线性雾 雾效因子二、MixFog1、ComputeFogIntensity 雾效强度计算2、雾效颜色混合 lerp(fogColor, fragColor, fogIntensity); 前言 在之前的文章中,我们实现了URP下的雾效支持。 Unity中URP下的添加雾效支持 在上一篇文章中,我们解析了 URP 下统…

HCIA-Datacom题库(自己整理分类的)——其他网络协议【完】

(一)单选 下列属于链路状态协议的是? Direct static FTP OSPF 解析: FTP:文件传输协议 OSPF:链路状态路由协议 如下图所示的网络主机A通过Telnet登录到路由器A然后在远程的界面通过FTP获取路由器的配置文件&…

【已解决】Invalid bound statement (not found)

报错讯息 org.apache.ibatis.binding.BindingException: Invalid bound statement (not found): com.casey.mapper.SysRoleMapper.getUserRoleCode at org.apache.ibatis.binding.MapperMethod S q l C o m m a n d . < i n i t > ( M a p p e r M e t h o d . j a v a :…

iec104和iec61850

iec104和iec61850 IEC104 规约详细解读(一) 协议结构 IEC104 规约详细解读(二)交互流程以及协议解析 61850开发知识总结与分享【1】 Get the necesarry projects next to each other in the same directory; $ git clone https://github.com/robidev/iec61850_open_server.g…

【GoLang入门教程】Go语言几种标准库介绍(四)

编程语言的未来&#xff1f; 文章目录 编程语言的未来&#xff1f;前言几种库fmt库 (格式化操作)关键函数&#xff1a;示例 Go库标准库第三方库示例 html库(HTML 转义及模板系统)主要功能&#xff1a;示例 总结专栏集锦写在最后 前言 上一篇&#xff0c;我们介绍了debug、enco…
最新文章