【Distributed System】分布式 Session(Distributed Seesion)

Posted by 西维蜀黍 on 2019-11-10, Last Modified on 2022-12-10

Background

Session的作用?

Session 是客户端与服务器通讯会话跟踪技术,服务器与客户端保持整个通讯的会话基本信息。

客户端在第一次访问服务端的时候,服务端会响应一个sessionId并且将它存入到本地cookie中,在之后的访问会将cookie中的sessionId放入到请求头中去访问服务器,如果通过这个sessionid没有找到对应的数据那么服务器会创建一个新的sessionid并且响应给客户端。

分布式Session存在的问题?

假设第一次访问服务A生成一个sessionid并且存入cookie中,第二次却访问服务B客户端会在cookie中读取sessionid加入到请求头中,如果在服务B通过sessionid没有找到对应的数据那么它创建一个新的并且将sessionid返回给客户端,这样并不能共享我们的Session无法达到我们想要的目的。

分布式session管理实现方案

分布式Session有如下几种实现方式。

1 Session复制

任何一个服务器上的session发生改变(增删改),该节点会把这个 session的所有内容序列化,然后广播给所有其它节点,不管其他服务器需不需要session,以此来保证Session同步。

  • 优点:代码上不需要做支持和修改。
  • 缺点:需要对应支持session 复制的Web服务器,会对网络负荷造成一定压力,如果session量大的话可能会造成网络堵塞,拖慢服务器性能。
  • 适用场景:只适用于Web服务器比较少且Session数据量少的情况。
  • 可用方案:开源方案tomcat-redis-session-manager,暂不支持Tomcat8。

2 Session粘滞

将用户的每次请求都通过某种方法强制分发到某一个特定Web服务器上。具体来说,用户第一次请求时,负载均衡器将用户的请求转发到了A服务器上,那么用户以后的每次请求都会转发到A服务器上。

  • 优点:使用简单,没有额外开销。
  • 缺点:一旦某个Web服务器重启或宕机,相对应的Session数据将会丢失,而且需要依赖负载均衡机制。
  • 适用场景:对稳定性要求不是很高的业务情景。

3 Session集中管理

在单独的服务器或服务器集群上使用缓存技术,如Redis存储Session数据,集中管理所有的Session,所有的Web服务器都从这个存储介质中存取对应的Session,实现Session共享。

  • 优点:可靠性高,减少Web服务器的资源开销。
  • 缺点:实现上有些复杂,配置较多。
  • 适用场景:Web服务器较多、要求高可用性的情况。
  • 可用方案:开源方案Spring Session,也可以自己实现,主要是重写HttpServletRequestWrapper中的getSession方法。

4 基于Cookie管理

这种方式在每次发起请求的时候,都需要将Session数据放到Cookie中传递给服务端。

  • 优点:不需要依赖额外外部存储,不需要额外配置。
  • 缺点:不安全,易被盗取或篡改;Cookie数量和长度有限制,需要消耗更多网络带宽。
  • 适用场景:数据不重要、不敏感且数据量小的情况。

微服务架构中的分布式 session

Web应用持续发展,虽然进行了一定的拆分,把过去单体架构的巨石应用切割成了由若干个模块组成的分布式应用,但随着不断的迭代开发,这些模块应用依然会变成巨石应用,代码维护成本直线上升。

尽管可以再次进行应用拆分,但是随着拆分的应用增多,这些应用的编译、打包、部署和整合也成为了新的难题。在这样的一个环境之下,微服务架构开始受到广泛关注。

微服务架构即将一个应用拆分成一套小而相互关联的微服务,微服务之间通过暴露出来的API被其他微服务或系统所调用,在运行时,每个微服务实例通常是一个云虚拟机或一个Docker。众多微服务综合起来,构成了一个完整的微服务架构应用。

微服务架构中的微服务一般可以分为两类:无状态服务和有状态服务。无状态服务比如应用服务器,它们通常是不保存数据的,方便进行横向扩展;有状态服务需要进行数据存储,比如数据库服务和缓存服务。在Web应用中,Session用来存储用户的状态信息,所以Session管理也是有状态服务器的一种。


在分布式架构中,Session管理方案是将用户Session存放在Web服务器内存中,然后通过Web服务器的复制能力或者负载均衡器的请求分发能力来实现Session共享。但是在微服务架构的实践中,企业对大型应用进行微服务改造,让应用向云环境迁移,通常会将应用拆分成十几个甚至数十个微应用,如果仍然使用Session复制、粘滞,不但会带来很多的不必要资源开销,还会降低整个企业应用的可用性和安全性。

因此,在微服务架构下,对Session的管理应该另辟蹊径,不再将Session对象保存在Web服务器内存中,而是在应用服务器架构中引入独立的中间存储介质,将企业应用中的Session对象进行统一管理。

一个好的Session集中管理方案应该具备以下特点:

  • 中间存储介质的读写速度要快。之前的Session管理方案将Session对象存放在服务器内存中,有着很高的读写速度,进行Session集中管理后将会在Session读写中引入网络传输,速度会有所降低,所以必须保证中间存储介质的读写速度。
  • **中间存储介质要保证高可用。**进行Session集中管理后,整个企业应用的Session都会存放在中间存储介质中,如果存储介质是不稳定的,那整个企业应用都将不稳定。
  • 对Session的使用者来说,Session管理方案应该是透明的,
  • Session管理方案不该和某一Web服务器耦合,应该适用于所有常规Web服务器。

Reference