解决集群Session共享问题
1. Session Sticky
让负载均衡器能够根据每次的请求的会话标识来进行请求的转发,这样就能保证每次都能落到同一台服务器上面,这种方式称为Session Sticky方式。如下图:
存在问题:
1. 如果这一台Web服务器宕机或者重启了,服务器上的会话数据会丢失,用户需要重新登陆等。
2. 会话标识是应用层的信息,那么负载均衡器要将同一个会话的请求都保存到同一个Web服务器上的话,就需要进行应用层的解析,这个开销比第四层交换(LVS负载均衡器属于第四层)要大。
3. 负载均衡器变为一个有状态的节点,要将会话保存到具体的Web服务器的映射。和无状态的节点相比,内存消耗会更大,容灾方面会更麻烦。
打个比方,比如Web服务器是饭店,会话数据是碗筷。要保证每次吃饭都用自己的碗筷的话,我就把餐具存在某一家饭店,并且每次都去这家店吃饭。
2. Session Replication
还是以吃饭的例子,如果我们在每个饭店都存放一套自己的碗筷,就可以自己的选择去哪家吃饭了。这就是Session Replication。如下图:
此方案不用再要求负载均衡器保证同一个会话的多次请求必须到同一个Web服务器上了。我们在Web服务器之间增加了会话数据的同步,通过同步就保证了不同Web服务器之间Session数据的一致。一般应用容器都支持Session Replication方式,与Session Sticky方案相比,Session Replication方式对负载均衡器没有那么多的要求。
存在问题:
1. 同步Session数据造成了网络带宽的开销。只要Session数据有变化,就需要将数据同步到所有其他机器上,机器越多,同步带来的网络带宽开销就越大。
2. 每台Web服务器都要保存所有Session数据,如果整个集群的Session数据很多(很多人同时访问网站)的话,每台机器用于保存Session数据的内容占用会很严重。
这个方案是靠应用容器来完成Session的复制从而解决Session的问题的,应用本身并不关心这个事情。
这个方案不适合集群机器数多的场景。如果只有几台机器,用这个方案是可以的。
3. Session数据集中存储
将Session数据集中存储,然后不同Web服务器从同样的地方获取Session,如下图:
Session数据不保存到本机而且存放到一个集中存储的地方,修改Session也是发生在集中存储的地方。Web服务器使用Session从集中存储的地方读取。这样保证了不同Web服务器读取到的Session数据都是一样的。存储Session的具体方式可以是数据库、分布式存储系统等。这个方案解决了Session Replication方案中内存的问题,对于网络带宽也比Session Replication要好。
存在问题:
1. 读写Session数据引入了网络操作,这相对于本机的数据读取来说,问题就在于存在时延和不稳定性,不过我们的通讯基本都是发生在内网,问题不大。
2. 如果集中存储Session的机器或者集群有问题,就会影响到我们的应用。
相对于Session Replication,当Web服务器数量比较大、Session数比较多的时候,这个集中存储方案的优势是非常明显的。
4. Cookie Based
这个方案对于同一个会话的不同请求也是不限制具体处理机器的。它是通过Cookie来传递Session数据的,如下图:
从上图可以看出,我们的Session数据放到Cookie中,然后在Web服务器上从Cookie中生成对应的Session数据。这就好比我们每次都把自己的碗筷带在身上,这样去那家饭店就可以随意选择了。相对前面的集中存储方案,不会依赖外部的存储系统,也就不存在从外部系统获取、写入Session数据的网络时延、不稳定性了。
存在问题:
1. Cookie长度的限制。我们知道Cookie是有长度限制的,而这也会限制Session数据的长度。
2. 安全性。Session数据本来都是服务端数据,而这个方案是让这些服务端数据到了外部网络及客户端,因此存在安全性上的问题。我们可以对写入的Cookie的Session数据做加密,不过对于安全来说,物理上不能接触才是安全的。
3. 带宽消耗。指的是我们数据中心的整体外部带宽的消耗。
4. 性能影响。每次HTTP请求和响应都带有Session数据,对Web服务器来说,在同样的处理情况下,响应的结果输出越少,支持的并发请求就越多。生成Session数据也会影响处理速度。
这4个方案都是可用的方案,但是对于大型网站来说,Session Stick和Session数据集中存储是比较好的方案,这两个方案各有优劣,需要在具体的场景中做出选择和权衡。