SESSION的工作原理
Session是HTTP服务器开发必备的知识,当用户访问网站并且登陆之后,服务器需要标识这个用户,这个时候就需要用到Session。
如果没有Session,那么每次用户访问服务器的时候,服务器都无法识别用户,这样就无法实现用户的登陆状态,无法为用户提供个性化的服务。
后端开发中,Session是必须了解的开发知识,但是大部分人对Session的理解就是数据存储在服务器的内存中,没有想过Session的存储位置,也没有想过Session的共享问题。
稍微有点规模的业务都需要考虑Session的共享问题,比如多个服务器之间的Session共享,比如多个域名之间的Session共享,比如多个系统之间的Session共享。
Session与Cookie的不同之处
Cookie是一种在客户端存储用户信息的机制, Session是存储在服务器端。 两个的差别就是一个存储在客户端,一个存储在服务器端,都是用来存储会话用户的信息。
大部分情况下Session会依赖Cookie的机制来实现:
- 当用户第一次访问服务器的时候,服务器会生成一个SessionID,
- 将这个SessionID存储在Cookie中,同时将这个SessionID存储在服务器端
- 当用户再次访问服务器的时候,服务器会通过Cookie中的SessionID来查找对应的Session信息
也就是所有的Session方案都需要在客户端中存储一个SessionID,客户端访问服务端的时候,需要提供这个SessionID, 最简单的方式就是存储在Cookie中。
为什么要共享SESSION
HTTP服务器为了保证高可用,一般会有多台服务器提供服务,意味着用户的HTTP请求可能会随机分配到不同的服务器上,这就会导致用户的Session信息无法共享,这时候就需要有个机制共享Session信息
7种SESSION共享方案
接下来介绍几种常见的Session共享方案,以及各自的优缺点
1. Cookie
Cookie是一种在客户端存储用户信息的机制,Session是存储在服务器端,两者结合可以实现Session共享。
因为HTTP请求的时候会把Cookie信息带上,所以可以在服务端上将Session加密后存储在Cookie中 当下次请求的时候,服务端可以通过读取Cookie的Session信息后解密得到Session信息。
优点:
- 性能高
- 简单易用,无需额外的存储
- 不受服务器限制
缺点:
- 不能跨域
- 存储信息小,Cookie能存储的信息很少,量大会导致HTTP访问流量增大
- 安全性差,密钥泄露后会导致Session信息泄露
2. JWT
JWT是一种用于在网络上传输信息的简洁的、自包含的标准方法,可以在不同域名的服务器之间共享Session信息
主要用在前后端分离或者不同Domain之间共享Session信息。
JWT有个Payload,可以存储用户信息和一些自定义的信息,比如用户的权限等, 客户端每次访问服务端的时候,只需要带上JWT的Token,服务端就可以通过Token解析出用户的信息。
JWT也可以作为Cookie的一部分,存储在Cookie中
优点:
- 性能高
- 简单易用,无需额外的存储
- 可以跨域共享
缺点:
- 安全性差,密钥泄露后会导致Session信息泄露
- 存储信息小,量大会导致HTTP访问流量增大
3. 数据库
数据库是一种常见的Session共享方案,可以将Session信息存储在数据库中,不同的服务器可以通过数据库来共享Session信息。
Session信息通过序列化后存储在数据库中,不同的服务器可以通过SessionID来查找Session信息
优点:
- 存储信息大
- 可以跨域共享
- 可以持久化存储
- 可以通过数据库的事务来保证Session的一致性
- 安全性高,数据储存在服务端
缺点:
- 性能差,每个HTTP请求都需要访问数据库
4. 共享文件系统NAS
共享文件系统NAS是一种常见的Session共享方案,可以将Session信息存储在共享的文件系统中,不同的服务器可以通过文件系统来共享Session信息。
Session信息通过序列化后存储在文件系统中,不同的服务器可以通过SessionID来查找Session信息
优点:
- 存储信息大
- 可以跨域共享
- 可以持久化存储
- 安全性高,数据储存在服务端
缺点:
- 性能差,每个HTTP请求都需要访问文件系统
- 文件系统的性能和可靠性要求高,文件访问没有数据库连接池高效
5. 缓存服务器 Redis最常用
为了解决数据库的性能差的问题,可以使用缓存服务器来存储Session信息,比如Redis,Memcached等。 工作原理同数据库,只是将Session信息存储在缓存服务器中,不同的服务器可以通过缓存服务器来共享Session信息。
Redis的方案可以比数据库提升至少10倍的性能,可以通过缓存服务器的集群来保证高可用。
优点:
- 性能高
- 存储信息大
- 可以跨域共享
- 安全性高,数据储存在服务端
缺点:
- 可能会丢失数据,缓存服务器是内存存储,可能会丢失数据
- 需要额外的存储,需要额外的缓存服务器
6. Sticky Session
当多个服务器是通过挂载在负载均衡器上的时候,可以通过Sticky Session来实现Session共享。
所谓的Sticky Session就是当用户第一次访问服务器的时候,负载均衡器会将用户的请求固定分配到后端的实例中
当用户再次访问的时候,负载均衡器会将用户的请求转发到同一台服务器上
那么用户所在的服务器就可以确保这个用户的Session都储存在一台服务器上。
优点:
- 性能高
- 简单易用,无需额外的存储
- 存储信息多
缺点:
- 不能跨域
- 可能会导致服务器的负载不均衡
- 可能会导致服务器的单点故障
- 负载均衡器的配置难度大
7. Session服务器
最后一种方案适合大型的系统,可以专门搭建一个Session服务器,用来存储Session信息,所有的Session信息都通过这组服务器来存储和读取。
这种方案可以保证Session信息的一致性,可以保证Session信息的安全性,可以保证Session信息的高可用性。
优点:
- 性能高,可以通过缓存来提高性能,减少序列化开销
- 存储信息大
- 可以跨域共享
- 安全性高,数据储存在服务端
- 可以通过Session服务器的集群来保证高可用
缺点:
- 需要额外的存储,需要额外的Session服务器
- 需要额外的网络开销,需要额外的网络开销
- 需要额外的维护,需要额外的维护
总结
整理一个表格,大家分别从存储位置、性能、安全性、可用性、跨域等方面来选择合适的Session共享方案:
方案 | 存储位置 | 性能 | 安全性 | 可用性 | 跨域 | 适合规模 |
---|---|---|---|---|---|---|
Cookie | 客户端 | 高 | 低 | 高 | 不能 | 小规模 |
JWT | 客户端 | 高 | 低 | 高 | 能 | 中规模 |
数据库 | 服务端 | 低 | 高 | 中 | 能 | 小规模 |
文件 | 服务端 | 低 | 高 | 低 | 能 | 小规模 |
单机缓存 | 服务端 | 高 | 高 | 中 | 能 | 中规模 |
Sticky Session | 服务端 | 高 | 低 | 低 | 不能 | 大规模 |
Session服务器 | 服务端 | 高 | 高 | 高 | 能 | 大规模 |
大家可以根据自己的需求来选择合适的Session共享方案,不同的系统有不同的需求,需要根据自己的需求来选择合适的Session共享方案。
如果大家对后端编程有兴趣可以关注我们的公众号(入职啦 ruzhila),我们会定期更新后端编程的开发知识。
也可以加入我们的编程交流群,一起学习,一起进步。