我是少侠露飞。学习塑造人生,技术改变世界。
引言
cookies和session是前后端开发不得不去正视的概念,也是面试中的高频面试点。但是cookies和session的区别,以及分布式session的解决方案,你真的掌握了么?本篇侧重从这两个方面介绍。
cookies和session的区别
首先要明白为什么有cookies和session。
由于HTTP协议是无状态的协议,所以服务端需要记录用户的状态时,就需要用某种机制来识具体的用户,这个机制就是session.典型的场景比如购物车,当你点击下单按钮时,由于HTTP协议无状态,所以并不知道是哪个用户操作的,所以服务端要为特定的用户创建了特定的session,用用于标识这个用户,并且跟踪用户,这样才知道购物车里面有几本书。这个session是保存在服务端的,有一个唯一标识。在服务端保存session的方法很多,内存、数据库、文件都有。集群的时候也要考虑Session的转移,在大型的网站,一般会有专门的Session服务器集群,用来保存用户会话,这个时候 session信息都是放在内存的,使用一些缓存服务比如Redis之类的来放 session。
那么服务端是如何识别特定的客户呢?
这个时候cookies就登场了。每次HTTP请求的时候,客户端都会发送相应的cookies信息到服务端。实际上大多数的应用都是用 cookies来实现session跟踪的,第一次创建session的时候,服务端会在HTTP协议中告诉客户端,需要在 cookies里面记录一个sessionID,以后每次请求把这个会话ID发送到服务器,我就知道你是谁了。有人问,如果客户端的浏览器禁用了 cookies怎么办?一般这种情况下,会使用一种叫做URL重写的技术来进行会话跟踪,即每次HTTP交互,URL后面都会被附加上一个诸如 sid=xxxxx 这样的参数,服务端据此来识别用户。
cookies用来保存网站密码
cookies其实还可以用在一些方便用户的场景下,设想你某次登陆过一个网站,下次登录的时候不想再次输入账号了,怎么办?这个信息可以写到cookies里面,访问网站的时候,网站页面的脚本可以读取这个信息,就自动帮你把用户名给填了,能够方便一下用户。这也是cookies名称的由来,给用户的一点甜头。
所以,总结一下:session是在服务端保存的一个数据结构,用来跟踪用户的状态,这个数据可以保存在集群、数据库、文件中;cookies是客户端保存用户信息的一种机制,用来记录用户的一些信息,也是实现session的一种方式。
分布式session的解决方案
经过上面的粉分析,我们已经知道,cookies是保存在浏览器的,session是保存在服务器。那么在分布式服务中,如何解决session的问题呢?
1 Session Sticky
在分布式环境中,保证同一会话每次都由同一台服务器处理。就好像在单机环境下处理一样,这就叫Session Sticky。
要实现此,目前主要是负载均衡器根据请求的会话标识来做请求转发,比较典型的如Nginx的IP哈希,能保证每次同样的客户端请求都打到同一台服务器上来处理。
此方案主要缺点如下:
- 如果一台服务器宕机或者重启,机器上的所有会话数据都会丢失,相关的用户就要重新登录。
- 会话标识是应用层的消息,那么负载均衡器需要将同一会话的请求都保存到同一个服务器上的话,就需要进行应用层(第7层)的解析,这个开销比第4层的交换要大。
- 负载均衡器变为了一个有状态的节点,要将会话保存到具体服务器的映射。和无状态的节点相比,内存消耗会更大,容灾方面会更麻烦。
2 Session Replication
分布式服务器之间进行session的同步和备份。主要是靠应用容器来完成session的复制从而使得应用解决session问题的,应用本身并不需要关心session同步的事情。
此方案带来的问题如下:
- 同步session数据造成了网络带宽的开销。只要session数据有变化,就需要将数据同步到所有其它服务器上,机器数量越多,同步带来的网络带宽开销就越大。
- 每台服务器都需要保存所有的session数据,如果整个集群的session数据很多的话,每台机器用于保存session数据的内存占用会很严重。
因此,该方案并不适合集群机器数较多的场景,如果只有几台机器,可以考虑用这个方案。
3 Session数据集中存储
同样是希望一个会话请求可以转发到不同的服务器上,刚才的session replication是一种方案,另一种就是这里要介绍的session数据集中存储。
那么该方案的问题是什么呢?
- 读写session数据引入了网络操作(相对于本机的数据读取而言),问题就在于存在时延和不稳定性,不过我们的通信都发生在内网,问题不大。
- 如果集中存储session的集群发生了问题,就会影响我们的应用。
4 Cookie Based
和前面的思路不同的是,该方案是通过cookie来传递session数据的,即把session存放在cookie中。
不过这个方案依然存在不足:
- cookie长度的限制,进而限制了session数据的长度。
- 安全性。session本来是服务端的数据,该方案使得服务端数据到了外部网络和客户端,因此存在安全性问题。
即使我们可以对cookie里的session数据加密,不过对于安全来说,物理上不能接触才是安全的。
- 带宽消耗。cookie中包含session数据,数据中心的整体外部带宽的消耗提高了
- 性能影响。每次HTTP请求和响应都带有session数据,对web服务器来说,在同样的处理情况下,响应的结果输出越少,支持的并发请求就会越多。
小结
对于大型网站来说,Session Sticky和Session数据集中存储是比较好的方案,而这两个方案又各有千秋,需要开发在具体的场景中做出选择和权衡。