代理和 Session 机制(4)|学习笔记

本文涉及的产品
应用型负载均衡 ALB,每月750个小时 15LCU
.cn 域名,1个 12个月
传统型负载均衡 CLB,每月750个小时 15LCU
简介: 快速学习代理和 Session 机制

开发者学堂课程【Tomcat 服务器入门详解代理和 Session 机制】学习笔记,与课程紧密联系,让用户快速学习知识。  

课程地址:https://developer.aliyun.com/learning/course/654/detail/10847


五、负载均衡

1、负载均衡问题

做负载均衡时几个问题,一台服务尤其是动态服务,其实响应能力还是比较差的。遇到高并发的时候,能力其实往往是不堪重负的。还希望多用户访问要做各种各样的优化,不能在一个点上着眼一点,肯定解决不了问题。

但是先来看问题在哪,到时候 Tomcat 看一下就变成这样了,变成这样带来最大的问题,有可能会出现 session 的问题实际上表面绘画,其实实际上是在编程过程中经常使用的一个东西,尤其是像有些人登录,登录之后会保留一个 session 值这么个东西。像刚才那个结构的话,就得重复通过前面然后进行调度,

从 Tomcat A,然后到 Tomcat B 到 Tomcat C,这就是假设是以文学最简单,这样就可能这一次请求到达了A,下一次你到达 B 到达 C 这本身按道理应该负载均衡,不就是减少压力但是会带来一个问题,问题不在于静态资源,因为静态资源每一台部署的一模一样,不是个问题,先不考虑缓存的问题如果是这样的话,动态有什么问题查查数据库吗,其实不在于数据库,而在于 session 的问题。

从最的 HTTP 一点 X 或者说零点几的版本,一直有的问题,这个阶段的包括 http的2.0协议。负载均衡有三个特点,第一个无状态,第二个有连接,

第三个短链接。

2、HTTP 的有连接和短连接

稍微简单的两点,第一个有连接协议,不用讲 http,目前用的这个版本是基于http,那么基于 http 都知道这有连接协议,以前是用连接的时候它是这样子的,首先发起一个 get 请求功之后,发起一个 TCP IP 的三次握手,然后连接在一起。

之后传出去,传完之后即刻断开,这时候网页过来之后还要对图片发信息请求,对css 文件发起请求,再创建每一个请求,再创建 TCP 连接,连接完之后再断开,对于客户端没有什么问题,但是对服务器端来讲的话,就有问题了,再一个 io 本来资源也是有限的,要是这么频繁的创建连接,代价有点高。在断开的时候,等待的断开的连接也比较多,这个实际上大大的影响服务器端的并发的响应能力连接太多,实际上对于对方来讲的话,io资源基本被耗尽了,那么为了解决这个问题,了一个 keep alive, 1.0之后是吧?

引入的不是长链接,是短连接,短到什么程度,不是说用完即断,而是用完之后浏览器别着急断开,看看有没有其他的请求。

所以连接对服务器产生压力,不管怎么样,物理上的 TCP 的连接,当然是逻辑通畅,就是这个连接会维持一段时间,减少与服务器中建立的这些连接这样的话服务器就可以留出更多的 io 资源,然后响应其他的请求,这是我们说的有连接和短连接的意思,这是目前我们所使用的版本。

3、HTTP 的无状态

(1)解决状态

在当初创建 HTTP 协议的时候,没有想到今天应用,所以当时没有解决一个问题无状态。

什么无状态呢,简单的讲就这么意思。浏览器发起的第一次 get 请求过去给你一个响应,成再发起一次请求,不管是什么请求,在服务器收到这个请求之后,根本无从判断,根本不知道这两次请求之间有任何的联系这个当初很好,想想回到最原始的状态,在90年代初去创建这个协议的时候是个什么状态就算那个地方它放的那些服务器已经厉害的服务器,但是扛得住那些压力,当时那服务器扛不住这些良机连接所以当时在想什么,就是想看一篇研究文档文档能有几千字,看归你看,实际上点下一超链接什么时候,根本不知道是不是看完这一页就不再看了,也不知道点超链接是什么时候就跳转到下一页,也就是说下一次请求到底什么时候发,根本就不知道。

再一个我服务器不可能保持一个长连接,等着下一次请求,会不堪重负,所以当年包括网络带宽,包括当年的服务器,都没有办法去满足这么多并发的压力,所以当时就用完即断。服务器还要响应其他人的请求的,不应该是为了未来什么时候要到来,就可以把这条连接给你,一直保持着。

所以当时的设计阶段是很合理的。但是没想到后来竟然有个动态网页,像JSP这种的动态网页技术出现了,动态网页出现之后,它的应用场景就不一样,得知道这个用户是谁,知道这个用户是比如说你要登录的,登录之后,第二次发请求,都不知登录过,就一直在那登录再也进不来了,这没法用了,再登录之后再给身份标识,不然怎么读取你用户个人信息,得知道个人信息是什么,所以这些问题就随之带来了。

这是当初没有想到的,因为当初只设计了静态网页这种东西,没考虑到以后还有这种场景。当年有这样的创举已经很不错了,但是没有真正想到互联网能走到今天这样,所以这就带来问题了,如何解决状态的问题。

当然在这之前还没有人着急解决这个问题,但是在这之前王景公司在那想办法解决不是说要解决这个问题,意思是发请求的时候能不能带出去,两边能不能交换一些数据,除了查询字符串还能不能有其他交互数据的方式,而且这个数据还能长久保存一会,还互不影响,指的是跨域,不能互相影响。所以发明了 cookie 技术。

(2)cookie 技术

cookie 技术是什么,就是浏览器本身在一起,按照不同,因为这是安全性的问题。

为了安全起见,按不同为每一个能够单独在浏览器本地,在浏览器里面跟服务器没关系,在浏览器本地存储,本地存储,也就是说可以持久化保存,所以把浏览器彻底关了,进程都关了再打开,是持久化过的,可以独取出来,独立出来。

那么在浏览器本地可以保存一些与域相关的,这些 cookie 就能干嘛,当发起对域相同的域发起请求,发起 HTTP 请求的时候,会将这些 cookie 值这些 kv 队全部带过去,带到在 request 的 hide 部分,有一个是 cookie 这样的就带上了,就带上这些值就是一堆的值,谁等于谁,就这值就带过去了。

这带过去以后服务器就可以从 HTTP 请求头当中分析出这些值,就解析出现值了,截取这一值。这是当时就是用这种方式可以带一些指导服务器端,这些职能按道理可以在客户端自己创建,在客户端自己创业。没有这样做过,其实你可以这样做。发请求那不就文本了,那不就自己想怎么写就怎么写,就可以这么做,像有的时候自己去填一个,然后报到服务器端。

到服务器端就可以收到这个信息,可以做一些判断了或者为了判断用户登录的,不是只是为了解决数据传输的问题,而持久化保存的问题,服务器端可以什么服务器端可以主动的发起一个 response 的头。

在 response 头里面有一个session,Size cookie 它可以发这样一个头,塞在cookie 里面就写着 KV 这样的字符。

它通过 site 可以写好多每个 cookie 可以只写一个 KV,可以将这些 kv 队从服务器端,然后通过响应报文传回给浏览器一段,浏览器端看到了从服务器端回来的site,cookie 就会把这些 cookie 值保存在与当前域相关的一个名词空间下面,或者说一个存储到与当前域名相关的存储起来。

(3)跨域

图片9.png

随便打开一个,里面其实应该是有一些的 F12,F12 打开之后在这儿可以看到,在这个里面有一个 application,education 这块点开以后就是与当前域相关的主意。

Ip 是一个,虽然也可以解析成这个IP地址,但是算不同的,这就跨域问题了,这已经是跨越问题了。

协议不同,IP 不同、端口不同,这都算不同的域。以后可能会遇到一些跨越问题,有时候在给人部署的时候,可能调入 rest of 那种接口,而 risk 那种接口的话,比如说 a reserve 接口可能大家以后会遇得到,大概说一下。在部署的时候可能会看到,因为要面向服务部署的话,

比如可以是这么一个接口,

http://www.magedu.com/api/v1/xxxx/yyyy

http://api.magedu.com/v1/xxxx/yyyy

这种这是 resume 风格的。然后这种就不存在跨越了,因为当前也访问,假如是三W 的内容,就不存在跨越。

但是有可能有的是访问,要访问这种问题了。然后这就不用 API 了,直接 V 一就可以的。当然不是这个地方这个清楚了,这个接口是访问这个的,这都是有可能这是跨越了。所以访问这种如果是前面访问的都是这样一个域名的话,就说明不跨越,但是这域名就跟上面就跨越了,这就是跨越问题,所以这个了解一下就行了。什么是跨越?就是协议不同。APP 有一个 APS,这已经跨越了。

再一个就像域名不同,包括主机在内,域名不同,还有就是端口不同等等,这是跨越问题。这个东西一般来讲,并不在客户端创建,它是你访问服务器端以后有服务器端带回来的 response,报文里面有 cookie,然后就把这些 cookie 存储当前域相关的一个存储空间当中去了。存储之后还是 KV 对,只不过它有它格式,什么格式呢,K 是什么,V 是什么然后是跟哪个域相关的,然后是访问哪个路径才行,这个是访问所有路径相当于只要前缀匹配型,这个是前缀是根下的 manager 之下的所有的才会用到这个信息。而且他们是 session 的,代表现在不是按照时间过去的,不是多少过期,也不是在某个时间点过,也就是这个窗口要是关了,或者当前浏览器有关了,那就没了。

注意 session 绘画集就与当前连接有关,这连接断了这个 session 就没了,注意这是浏览器做的,session 是告诉浏览器应该怎么做,那要是自己写的浏览器呢,可以写一个没有界面像 curve 命令没有界面的浏览器,cookie 这东西一点都保不保险。然后后面这个地方HTTP owner意思是只允许 HTTP 传输请求的时候带上,不允许 JavaScript 脚本访问,不安全,自己写浏览器,想访问就访问了。

(4)安全运输

安全传输,传输安全不代表存储安全了,存储是明文存储的,传输就算用这个选项,传输就是用 CS用的 SSL 加密没有用,他在两端的时候全是明文的,还是很容易被看清楚的。cookie 里面禁止使用敏感信息,禁止使用敏感连接。也就是这东西其实不安全,所以不要以为这东西很安全了。cookie 伪装是非常难对付的,把这个值记录下来之后,关闭,浏览器关服务器根本就不知道,因为从来没给服务器发请求,然后就跟直接不安全了。服务器都不知道。


六、session 机制

1、session 机制理解

解一下 session 机制,动态网页技术之后诞生的,跟上一个请求有关系不能发个1234,然后保留就行了,这东西被人记住了所以发一个随机的或者希值发过去每一次求的值都是不一样的,把这个值发给你在 response 报文当中加 Site,cookie。这是不是加个 cookie名字很特别是 session ID。

当然因为这个是跟 Java 相关的,session ID 不管大多数情况下都section ID,记住就行了。

Session ID 是从服务器端它的 set cookie 回来的,打开的晚了,主要是没看到,session 的 cookie 回来之后,浏览器看到之后就会把 copy 保存,有可能会告诉浏览器说这东西 HTTP,session 级别,然后浏览器按你的来,浏览器一关,就消失不持久化。

再一个我不允许我禁止 GS 直接访问可以了,这就是浏览器做的,当然大多数都下都是正规的浏览器还是要做到这一点了,但是架不住浏览器是你自己写那么服务器端给你发回的随机的 session ID,然后下回存到自己的 cookie 上下回发起请求的时候,这个值带上之后,在 request 的请求当中他就带往了服务器端。服务器端有请求来了,然后一看 cookie 里面竟然有个是 session ID 取出来,取出来之后怎么认识要存才能行,要存内存是没问题的。

2、快速查询

怎么才能快速查询到呢要用到技术,就是类似于mapping 或者字典的技术,就在学院拍摄的时候,里面有个字典。

可以做的时间复杂度,那就是一瞬间就找到了值,要做哈希的。直接进行比对,那就是一下就找到,而不是说用便利的方式说,来写个数组,从头到尾才知道有没有,不是这么做的,是直接求可以找到这个值,这个值有有没有一眼就看出来了,效率非常高,要放内存,放磁盘上那就没什么效率可言了。

一定是放内存的,类似于像 real estate 上结构希的方式很快就能找到,这个找到可以看,没找着是谁不认识你怎么办如有必要发现不认识这个用户,当然用户相关的信息不会给了,依然会要求你重新登录,或者说重新给你发放,注意如果是有必要的话,会重新给你发一个 sessionID,这个重新发一个 session ID 依然放在了 response 报文中的 session cookie 里面,回到了浏览器端,一看服务器又给我发把 kv队又存起来,上一次的session ID直接被覆盖掉了。

再发起请求带的就是新的, Session ID 值过去了。这回他一查这回认识,就会把session ID 相关的存储的一些信息,就会给返回了,个人信息就返还回来了,还是这么来做的。这就是 session 和 cookie 的作用机制。

3、反向代理多机

图片10.png

所以了解这一点之后,我们下面就可以看,如果是这种情况,有什么问题?

把这几个记为 a,b,c。当通过调度请求,第一次请求的时候,假设就是被调度到了A这台服务器,那么a这台服务器一看,第一回来你是的然后你把 session ID 通过它返回到浏览器,浏览器一看本域相关的 cookie 值来了,不管是不是绘画机,要临时一下,把 session ID 就存在于本域相关的存档页,它叫 session ID ,然后它的值是 session ID 1接下来以后临时用,发起请求,这一回用蓝色表示,他会把它调度到了 B 或者 C 上的假设就简单点到 B 这台服务器,被调到 B 服务器上,B 服务器一看这 session ID 谁发的,注意这是一个谁,可以认为是个随机值。

虽然它是个大整数,可以认为它是随机的,随机了以后 B 一看这谁发的,不是我发的,不认识你,不管是谁发,反正不认识,说不定是伪造的,不认识你。

所以就会写一个叫 set -cookie 的这样一个 response 的响应头在这个里面又会配上一个 session ID,等于 session ID2, 这样 session ID2 就会回来,第二次发的请求,拿到的是 session ID 2,原来一被覆盖了没了。

第三次请求用绿色表示,第三次请求一被调度又调不到这台服务器了,因为不光调度,还调动别人了这一调度到了 A 服务器上,它带的是 sessionID2,一查这谁又不认识怎么办来再重新生成一个,咱们说反正叫 session ID3,总之不一样就行。这些东西又回来了,这一看完了,把 session 又改成 SID 又覆盖了,Session ID 不一样会导致什么结果,会发现今天什么事都不用做,光登录就够了。

还有一个的现象的时候,在写购物车的时候,一般登录之后都会一个session ID,然后在这边的服务器端实际上是一个类似于字典结构,还是个 kv 对比结构,这个K是什么里面就存着 session ID 值,这里面有好多一二等等,然后都会指向一个 value,都会各自指向自己的 value,value 非常复杂,这个 value 可能又是一个 PPT 结构,比如说在里面记录着你的名字什么,年龄什么都跟 ID有关,什么意思如果是 Id 配对成功以后发现是这个了,才会把这些信息才会交给你,也就是说才能看得到,如果 session ID 值不对,那么不对就告诉你该登陆了,如果对的话 session ID 上能对应上,就把这些存储在 K 下面的这种再来的多个键值对都能给你。

kv 队里面可以存什么,比如经常会在这里面,像购物车最早都是这么实现的,现在购物车都改那么多时间了,什么时间的话会出事了,客户会不高兴的,在里面怎么弄。

(1)例子

比如第一个商品就是 P一,P一 单买20件选20件,然后第二个商品你买30件,双11要购物了买了一大堆东西,很不幸,这回调度的时候,刚开始调度他把你放在方这台服务器上,现在一调度调到这台服务器上了,这台服务器上没有 session ID1这台服务器不认识会说你登陆,是不是给你个 sessionID既然登录了,再去请求一下购物车,结果这上面有你购物车信息了。

难道有人清空我的购物车其实不是的然后就觉得很奇怪就有这样的问题。

如果说登录完之后发起的请求,发起请求以后,结果现在又调度到了这台服务器上之后,是不是你的购物车又回来了再回来有 sessionID极其不可能,几乎是没有可能性了因为登录之后,人家给一个 session ID,是不是就是另一个 session ID。

session 存着第二台服务器,第一台服务器回过去之后,想拿购物车,连门都没了,有没有想过这拿不到这怎么办那没办法了,就算登录在第一台服务器上,拿到就是另一个 session ID 了,再也拿到 sessionID1 了,这一条数据就是废的。这数据在内存当中。

(2)内存垃圾

那么在内存当中,如果都是这么的话,内存当中垃圾是不是太多了筛选 ID 将耗尽几乎所有的内存。同样真正要用的话,怎么可能网站就一天就5个人访问,所以这个网站它的访问量往往还是可观的。

session 怎么知道哪个不用了实际上两种方案,一种方案是登出,意思是主动的说再见,然后主动说再见,就主动把相关的所有 session 配对清除。但是一般是直接把关系都关了,还点登出,根本就不登出的。

所以在这上面要加绘画剖析,加多长时间合适,以前就是默认情况下是半小时,后来发现半小时有点长,有的网站15分钟,现在淘宝都不是15分钟,恐怕5分钟不登就要重新登录就过期了。

所以在这一点上对于像电商网站这种,基本上过期时间会很快,但是如果连续的发起请求,过期就在延续,相当于如果一碰它,过期时间就重新计算,倒计时要重新计算。

4、过期机制

过期机制就能解决连续问题了,但是如果登陆之后,都走了都不主动登出的话,会留很长一段时间了,如果是一个频繁的访问的网站,无效的筛选值在它过期之前其实也蛮多的,这个负担还是要有的。

这块如果由于是调度的不合理,还会带来问题,这个地方是很多无用的 session,只是因为调度不合理而重新生成的,这个也是垃圾,当然只能等过期了,谁也没办法访问了,只能等过去了。

在过期时间之前也不知道用户会不会来,所以只能是等过期,内存的负担是非常重的。

那么怎么样解决这个问题,当不同的调度,然后筛选值它必须被重新覆盖,然后再带过来,原来也就废掉,这个问题怎么解决这么一个 session ID1 谁发的A服务器发的,现在有可能被调度到B服务器和C服务器。

(1)方案

第一种能不能把你粘到这台 A 服务器上可以。粘到 A 服务器上,这样就不用到B服务器和 C 服务器上了

地址是应该要变了因为是拿地址时的,过往地址变了,这时候调度构不成又没了,所以这种方式也不好能不能不认 IP,认 sin 值Sin 值不变。通

过筛选值做希调度到某一台服务器上,这就更好一点IP 可能会出现一些问题,假设不太合适,某一些公共楼,现在这栋楼所有人都喜欢访问家网站是公网地址差不多应该是一样的,都被调到一些服务器,会出现服务器极不均衡,压力极不均衡的现象但是从整个放眼就是所有用户来看,好像不会出现特别的不均衡但是有的时候会偏了,最怕就是跑偏了。

这个问题在于 A 要是挂了,不管是用 session 还是 IP 的话,A 要是了,是不是被迫到 B 部门去了,赶紧要把它恢复上线,再回来是不是还有其实就算把这块的session 做持久化的,可以存到数据库里面去,也可以存到文件里面去,这可以做持久化,关键在没上线之前,他到这边去之后,sessionID 已经变,等再回来,就算持久化的恢复又能怎么样。

(2)服务端方案

服务端,服务推断想办法,其实有两种方案,第一种方案 session 的复制,A 上有什么 K 同步到 B 上去,同步到 C 上去。

挂任何一台都不是个问题但是问题又来了,每一个节点上都是 session 的全量,虽然做增量复制,但是实际上它是全量的 session,内存不堪重负,节点越多内存越大,而且内部通信同步通讯的话节点越多,同步通信越大。

因为同步通信,要从一个点是向其他点同步,而且还单薄,复制的,它是单薄复制的,这个时候压力就是比较大的,所以这个问题也得解决,用消息队列忙,其他地方还没讨论不完,这个时候做异步实际上有时候会有问题的。

消息队列不知道什么时候才能消费完,这个时候万一已经被调到那台服务器,还在消息队列里面是不是就要重新发 session ID 了甚至要重新登录,所以消息队列在里面不敢用,这地方不适合。

消息队列适合于什么呢发完之后不管了,什么时候用就什么时候消费,只要来得及就消费是这样。

前后完全不符合,在这种情况下同步,这不能做异步,只能做同步,否则会带来很大的问题。

因为下一个请求直接就被调到另一台服务器了这样是增量复制,然后每个上是有全量的副本数,内存消耗极大,然后节点越多,同步以及它是用多波进行心跳的,它是用单波复制的。

在这种情况下,实际上整个对网络带宽的消耗,以及同步时候做的这种等待,同步的代价会越来越高,所以这种适合小规模的。

要有最简方式服务器把 session 都放到上面畅通了,其实第三种方案是比较好的,所以可以用第三种方案比较好的解决这个问题,这是大多数企业用的。

相关文章
|
7月前
|
存储 缓存 搜索推荐
session 详解:掌握客户端会话管理
session 详解:掌握客户端会话管理
|
7月前
|
存储 前端开发 程序员
Session的工作机制
Session的工作机制
88 0
|
存储 网络协议 Java
网络基础 http 会话(session)详解
网络基础 http 会话(session)详解
488 0
|
缓存 Java 应用服务中间件
|
缓存 负载均衡 Java
|
缓存 负载均衡 Java
代理和 Session 机制|学习笔记
快速学习代理和 Session 机制
代理和 Session 机制|学习笔记
|
存储 安全 Java
|
存储
Cookie 原理 和 Session 原理的区别:
Cookie 原理 和 Session 原理的区别:
147 0
Cookie 原理 和 Session 原理的区别:
|
存储 开发框架 .NET
Cookie和Session的作用,区别和各自的应用范围,Session工作原理
Cookie和Session的作用,区别和各自的应用范围,Session工作原理
312 0