推荐https://blog.csdn.net/qinmengdeCluntan/article/details/77532883?locationNum=5&fps=1
针对庞大的用户访问压力,目前大多数大型网站服务器都采用集群部署的方式。在集群中我们需要考虑一个用户鉴权的问题,即在不同服务器下如何保证用户均已登录,并且获得相同的用户登录状态。
一、Java Web推荐的(公认的)用户鉴权机制
了解几个概念:
1、请求:Request,指客户端向服务器发送的信息。
2、响应:Response,服务器对请求的应答。
3、会话:Session,服务器可以将请求响应的一个完整的过程当做一次会话。并为这次会话生成唯一的标识符,即sessionId,用来表示这次会话,Session存储在服务端。
Java Web的用户鉴权采用的是Session-Cookie技术,实现的原理:用户登录时,请求到达服务器,服务器调用getSession()方法,首先判断Cookie是否为空,如果cookie为空,创建一个sessionId,并返回给客户端;如果Cookie不为空,判断服务器上是否存在cookie中携带的sessionID,如果不存在,创建一个sessionID,并返回给客户端,开发者可以在session中存储一些用户的数据。如果存在,返回sessionId对应的session data。
二、集群间如何实现session共享
在集群中,拥有多台服务器,每台各自为政,势必会造成在这台服务器中登录,获取session成功,但是到另一台服务器上,又会获取不到session,造成鉴权失败,这样对用户来说是极不友好的,那么怎么解决这个问题呢?
方法:
A:找一台公共的空间来存储session,每台服务器都能访问这块空间,从而实现session共享。
B:实时同步每一台服务器上的session信息。
方案:
1、持久化session到数据库,即使用数据库来存储session。数据库正好是我们普遍使用的公共储存空间,一举两得,推荐使用mysql数据库,轻量并且性能良好。
优点:就地取材,符合大多数人的思维,使用简单,不需要太多额外编码工作 。
缺点:对mysql性能要求较高,访问mysql需要从连接池中获取连接,又因为大部分请求均需要进行登录鉴权,所以操作数据库非常频繁,当用户量达到一定程度之后,极易造成数据库瓶颈,不适用于处理高并发的情况。
2、使用redis共享session。redis是一个内存数据库。将数据储存于内存中,并自带有内存到硬盘的序列化策略,即按策略将内存中的数据同步到磁盘,避免数据丢失,是目前比较流行的解决方案。
优点:无需增加数据库的压力,因为数据存储于内存中,所以读取非常快,高性能,并能处理多种类型的数据。
缺点:额外增加一些编码,以便操作redis。
3.使用memcache同步session,memcache可以实现分布式,可将服务器中的内存组合起来,形成一个“内存池”,以此充当公共空间,保存session信息。 优点:数据储存在内存中,读取非常快,性能好; 缺点:memcache把内存分成很多种规格的存储块,有大有小,不能完全利用内存,会产生内存碎片,浪费资源,如果储存块不足,还会产生内存溢出。
4.通过脚本或守护进程在多台服务器之间同步session。
优点:实现了session共享;
缺点:对个人来说实现较为复杂,速度不稳定,有延时性,取决于现实中服务运行状态,偶然性较大,如果用于访问过快,可能出现session还没同步成功的情况。
5.使用NFS共享session。NFS是Network File Server共享服务器的简称,最早由Sun公司为解决Unix网络主机间的目录共享而研发。选择一台公共的NFS做共享服务器,储存所有session数据,每台服务器所需的session均从此处获取。 优点:较好的实现了session共享; 缺点:成本较高,对于个人来说难以实现。NFS依托于复杂的安全机制和文件系统,因此并发效率不高。
6.使用Cookie共享session。此方案可以说是独辟蹊径了,将分布式思想用到了极致。如上文分析所说,session-cookie机制中,session与cookie相互关联,以cookie做中转站,用来找到对应的session,其中session存放在服务器。那么如果将session中的内容存放在cookie中呢,那么则省略了服务器保存session的过程,后台只需要根据cookie中约定的标识进行鉴权校验即可。 优点:完美的贯彻分布式的理念,将每个用户都利用起来,无需耗费额外的服务器资源; 缺点:受http协议头长度限制,cookie中存储的信息不宜过多;为了保持cookie全局有效,所以其一般依赖在根域名下,所以基本上所有的http请求都需要传递cookie中的这些标记信息,所以会占用一些服务器的带宽;鉴权信息全存储于cookie中,cookie存在于客户端,服务器并没有储存相关信息,cookie存在着泄露的可能,或则其他人揣摩出规则后可以进行伪装,其安全性比其他方案差,故需要对cookie中信息进行加密解密,来增强其安全性。