2021-06-23 17:02:16
Session是一种用于在HTTP无状态协议基础上实现用户状态跟踪的机制,主要用于解决服务器无法记住用户身份的问题。其核心原理是通过服务器生成唯一标识(Session ID),结合客户端存储的标识和服务器端存储的用户数据,实现会话状态的维护。
Session ID(钥匙):服务器为每个用户生成唯一的Session ID,通常通过Cookie发送给客户端。客户端后续请求会自动携带该ID,服务器通过ID识别用户。
存储用户数据(储物柜):服务器将用户数据(如购物车信息)与Session ID关联存储,可以是内存、文件或数据库。例如,PHP默认将Session数据存储在/tmp/phpsess_abc文件中。

具体流程:
首次请求:用户访问网站时,服务器未检测到Session ID,生成唯一ID并通过Cookie返回给客户端。
后续请求:客户端携带Session ID(如Cookie中的JSESSIONID),服务器根据ID查找对应的用户数据。
数据存储:用户数据以键值对形式存储在服务器内存或持久化介质中,例如Session["UserName"] = "23"会存储为sessionid=123, username=23。
Session的常见实现形式:
会话Cookie:未设置过期时间的Cookie,生命周期为浏览器会话期间,关闭浏览器后消失。
URL重写或隐藏表单:当浏览器禁用Cookie时,可通过URL参数(如?sessionid=123)或POST隐藏表单传递Session ID。
Session共享的目的是解决分布式系统中用户请求被分发到不同服务器时,Session数据不一致的问题。例如,负载均衡环境下,用户两次请求可能落在不同服务器,若Session数据仅存储在单台服务器,会导致数据丢失。
图:负载均衡下Session数据不一致问题实现Session共享的常见方法:集中式存储:
数据库存储:将Session数据存储在共享数据库(如SQL Server、MySQL)中,所有服务器从同一数据库读写数据。例如,ASP.NET支持通过配置文件将Session存储介质改为SQL Server。
优点:数据持久化,可靠性高。
缺点:数据库性能可能成为瓶颈,增加查询延迟。
客户端存储(加密Cookie):
原理:将Session数据加密后存储在客户端Cookie中,服务器通过解密Cookie获取用户状态。
优点:减轻服务器压力,无需共享存储。
缺点:
Cookie大小限制(通常4KB),无法存储大量数据。
每次请求需携带Cookie,增加带宽消耗。
用户禁用Cookie时失效。
服务器间同步:
原理:定时同步各服务器的Session数据,确保数据一致性。
优点:实现简单,无需额外存储。
缺点:
同步延迟可能导致数据不一致。
高并发场景下同步压力大。
分布式缓存:
原理:使用分布式缓存系统(如Memcached、Redis)存储Session数据,所有服务器通过缓存读写数据。例如,PHP支持将Session存储在Memcached服务器。
优点:
高性能,支持高并发。
数据自动过期,无需手动清理。
缺点:需额外维护缓存集群。
网络文件系统(NFS):
原理:将Session文件存储目录改为NFS共享目录,实现文件跨机器共享。例如,PHP可通过修改session.save_path指向NFS路径。
优点:无需修改代码,兼容性强。
缺点:NFS性能可能影响系统整体性能。
手动同步(简单场景):
原理:在用户首次设置Session时,通过POST请求将数据同步到其他服务器。例如,机器A设置Session后,将数据POST到机器B的CGI接口存储。
适用场景:Session数据不频繁变更的场景。
缺点:实现复杂,可能引入竞态条件。
通过合理选择Session共享方案,可确保分布式系统下用户状态的正确跟踪,提升用户体验和系统可靠性。