分布式环境下,如何实现 session 共享(How to Implement Session Sharing in a Distributed Environment)
💝💝💝欢迎来到我的博客,很高兴能够在这里和您见面!希望您在这里可以感受到一份轻松愉快的氛围,不仅可以获得有趣的内容和知识,也可以畅所欲言、分享您的想法和见解。

本人主要分享计算机核心技术:系统维护、数据库、网络安全、自动化运维、容器技术、云计算、人工智能、运维开发、算法结构、物联网、JAVA 、Python、PHP、C、C++等。
不同类型针对性训练,提升逻辑思维,剑指大厂,非常期待和您一起在这个小小的网络世界里共同探索、学习和成长。
1.Session简介
是一种用于维护客户端与服务器之间会话的技术。 它主要用于存储特定用户会话中的信息,确保在用户与服务器交互的过程中,数据不会丢失。
Session的基本工作原理如下:当用户通过浏览器访问网站时,服务器会为该用户创建一个唯一的Session对象。这个Session对象存储在服务器端,并通过一个唯一的标识符(通常是中的Cookield)与客户端进行关联。用户在进行页面跳转或发起新的请求时,服务器可以通过sessionId识别用户,从而恢复之前的会话状态。
2.Session的主要用途包括:
- 保存用户登录状态:在用户登录后,可以将用户的登录信息保存在Session中,确保用户在后续的请求中无需重新登录。
- 存储用户偏好设置:例如,如果用户不喜欢看到图形界面,可以将这一偏好保存到Session中,确保在用户的整个会话中都能看到无图界面。
- 实现购物车功能:在电子商务中中,Session可以用来保存用户的购物车信息,确保用户在浏览不同页面时,购物车中的内容不会丢失。
- 防止跨站请求伪造:通过Session可以验证用户的请求是否合法,防止未经授权的访问2。
3.Session与Cookie的区别:
Cookie通常用于存储少量的数据,并且可以被客户端禁用或删除;而Session将数据存储在服务器端,安全性更高,但依赖于客户端的Cookie来识别用户
4.在分布式环境下,实现Session共享的方法:
基于NFS的Session共享、基于数据库的Session共享、基于Cookie的Session共享和基于Memcached的Session共享。
-
基于NFS的Session共享:
NFS(Network FileSystem)是一种最早由Sun公司研发的技术,用于解决Unix网络主机间的目录共享问题。这种方法实现简单,不需要过多的二次开发,只需将共享目录服务器挂载到各个频道服务器的本地Session目录即可。然而,NFS依赖于复杂的安全机制和文件系统,导致并发效率不高,特别是对于高并发的读写操作,可能会因为共享目录服务器的I/O等待而导致前端WEB应用程序执行效率下降。 -
基于数据库的Session共享:
使用数据库存储Session是一种常见的解决方案,尤其是使用MYSQL的内存表Heap,可以提高读写效率。这种方法实用性较强,但缺点是Session的并发读写能力取决于MySQL数据库的性能。此外,需要实现session淘汰逻辑,以定时更新和删除session记录,高并发时可能会出现表锁问题,尽管可以选择行级锁的表引擎,但使用数据库存储Session在某些情况下显得大材小用。 -
基于Cookie的Session共享:
这种方法将用户的Session信息加密、序列化后以Cookie的形式存储,并种植在根域名下。当用户访问该根域名下的所有二级域名站点时,浏览器会自动传递Cookie,从而实现多服务间的Session共享。优点是不需要额外的服务器资源,但缺点是受HTTP协议头信息长度限制,只能存储少量用户信息,且需要进行安全加解密操作,占用一定的带宽资源。 -
基于Memcache的Session共享:
Memcache作为一种基于多路异步I/O技术的内存共享系统,以其高效的Key-Value数据存储模式在并发处理上表现出色。这种方法在处理高并发时具有显著优势,能够高效地处理大量的Session数据。
5.分布式环境下,如何实现 session 共享?
先了解一下为什么会出现这种session共享的解决方案?
随着互联网公司的项目在微服务和分布式的环境下进行的搭建,导致一个项目可能分别部署在几个甚至很多的服务器集群下,此时就会出现一个问题:
当用户进行一个session会话的时候,比如一个用户去登录项目,一般的大公司的项目都是有Nginx进行反向代理的,
这里简单列举一下Nginx常用的几种反向代理策略:
-
轮询策略,
-
权重比例策略,
-
ip_hash策略,
-
还可以自定义的策略,
在Nginx的反向代理下,一般会把用户的请求分发到不同的服务器上,但是如果用户请求的请求是存放在该请求的服务器A上,那么该用户的sessionID就存储在该服务器上JVM的一个ConcurrentHashmap中,以sessionID为key。
但是如果此时用户请求的一个服务模块可能需要调用到服务器B,当用户发起请求的时候,此时的服务器B上并没有存储该用户的sessionID,所以就会再次让用户进行一个登陆操作。还有可能会导致用户本来就想完成一个下单操作,但是却还登陆了好几次的情况。
所以session共享方案在分布式环境和微服务系统下,显得尤其重要。
5.1 解决方案一:基于Nginx的ip_hash 负载均衡
其实就是对请求过来的ip地址对你的多少台可用的服务器进行取模,然后就会把你的请求通过Nginx的反向代理给分发到对应的服务器上。(这里会把可用的服务器放到一个数组中,如果取模得到的结果是几,就把请求分到服务器数组中的下标为几的服务器上)
具体实现:
需要你在Nginx.conf文件中进行对应的修改,根据自己的可用服务器
upstream backend{
ip_hash;
server 192.168.128.1:8080 ;
server 192.168.128.2:8080 ;
server 192.168.128.3:8080 down;
server 192.168.128.4:8080 down;
}
server {
listen 8081;
server_name test.csdn.net;
root /home/system/test.csdn.net/test;
location ^~ /Upload/upload {
proxy_pass http://backend;
}
}
这种实现的优缺点:
5.2 解决方案二:基于Tomcat的session复制
这个解决方案其实就是当用户请求的时候,把产生的sessionID给复制到系统所有的服务器中,这样就能保证当用户请求的时候从服务器A可能调用到服务器B上的模块的时候,也能保证服务B也有该用户的sessionID,这样就不会再次让用户进行再次登录操作了。也就解决问题了。
具体代码中如何实现session复制呢?
使用session复制的优缺点:
5.3 解决方案三:使用Redis做缓存session的统一缓存
这种方案呢,其实就是把每次用户的请求的时候生成的sessionID给放到Redis的服务器上。然后在基于Redis的特性进行设置一个失效时间的机制,这样就能保证用户在我们设置的Redis中的session失效时间内,都不需要进行再次登录。推荐:250期面试题
如何进行代码的实现:
使用Redis实现session共享的优缺点:
5.3 解决方案四:结合cookie
其实还可以把session放到cookie中去,因为每次用户请求的时候,都会把自己的cookie放到请求中,所以这样就能保证每次用户请求的时候都能保证用户在分布式环境下,也不会在进行二次登陆。
更多推荐

所有评论(0)