session说到会话,相信每个程序员都不陌生,在项目中也或多或少用过。session这个词其实是一个抽象的概念,它并没有像Cookie一样有明确的定义。大多数程序员说到session,可能指的就是服务器端存储数据的session对象。比如用户登录成功后,在session中保存用户信息,类似这个程序。会话["用户名"]=newUser();publicclassUser{publicintUserId{get;set;}publicstringUserName{get;set;}}在计算机中,特别是在网络应用中,session被定义为“session”,可以认为是客户端和服务器之间的通道连接,并且同一个用户的请求使用同一个session会话。在大多数应用中,它主要用于用户识别。一般来说,服务器可以通过会话记录每个用户的状态信息。那我们就用最常用的服务器端session对象说几句吧。单机会话存储在服务器端,这是一个非常重要的概念。这意味着它需要占用服务器的内存,它需要一个释放机制来保证服务器的内存不会被爆掉(比如LRU)。项目前期,为了快速上线,服务器部署很多情况下只有一台服务器,一般采用session机制来记录用户的登录状态。请不要说这是不合理的,至少在项目的早期阶段,这种做法是最简单、最快的解决方案。随着项目的不断迭代升级,用户越来越多,你会发现单机系统已经成为项目最大的性能瓶颈。这时候,大部分架构师都会选择横向扩展的方案。其实,归根结底,系统性能的提升还是围绕着一个“分段”二字展开的。无论是数据库的分库分表,还是现在新兴的微服务,都是围绕一个领域进行切分的。单机的session机制横向扩展。面临必须解决的问题:如何解决session的亲和性(粘性)?当分布式会话的单机系统扩展为分布式系统时,将面临分布式CAP理论中AP和CP的差距。谈到分布式会话的一致性,其实主要是解决用户会话的亲和性。同一个用户的请求如何保证到达正确存储session信息的服务器呢?sessionreplication最初的解决方案是使用sessionreplicationSolution,整个过程很简单:假设现在有三台服务器,当在其中一台服务器上创建session时,同时将session复制到另外两台服务器上时间。这样无论用户的请求到达哪个服务器,都会有相应的session数据。这种方案的好处是可以对服务器进行任意级别的水平扩展,每个服务器都保留所有的会话信息。添加服务器时,只需要将所有会话信息复制到其中即可。但缺点更明显。所有会话信息都保存在每台服务器上,大大增加了服务器占用的资源。会话同步需要网络带宽。最重要的是,如果采用异步复制的方式,数据会暂时不一致,可能会导致用户访问失败。会话复制方案现在很少被负载均衡方案使用。当一台服务器扩展为多台服务器时,最常用的方案是在流量入口处加一个负载均衡器。总体部署图如下。如果负载均衡如果服务器可以使用一些手段来实现会话粘性,则可以实现分布式会话。目前主流的nginx可以根据“hash_ip”算法,将同一个IP的请求固定到某个服务器,让同一个IP的session请求总是到同一个服务器。这种方法比会话同步方法要好得多。每个服务器只存储对应的session数据,大大节省了内存资源,服务器之间没有数据同步过程。新增服务器时,只需要修改负载均衡器的配置,方便地支持服务器的水平扩展。但是,与此同时,也存在一些不足之处。服务器重启意味着相应的会话信息丢失,这在一些重要的业务场景中是不允许的。服务器水平扩展需要修改负载均衡器的配置。修改后可能会导致之前的session。重新分发,这将导致某些用户无法路由到正确的会话。会话剥离是现在应用比较广泛的分布式会话技术,就是将会话数据从业务服务器上完全剥离出来,单独存储在其他外部设备中,而这些外部设备可以采用主备或者主从,甚至集群模式来实现高可用性。例如,最常用的方案是将session数据存储在redis中。虽然从redis读写session数据需要一定的网络时间,但是对于一般的应用来说在可以接受的范围内。这种方案的好处是整体架构更清晰,更灵活。应用服务器的整体扩展能力不再需要考虑会话的影响,将会话的问题转移到外部设备上。通常,可以使用基于内存的NOSql来解决性能问题。这些外部设备一般都有相应的分布式集群方案,比如redis,可以采用master-slave或者sentinel模式甚至集群来提供更大规模的数据支持能力。Actor模型Actor模型会更优雅地解决这个用户粘性问题。它有自己的物体识别功能。简单地说,对同一个key的请求总能到达正确的actor实例。这不就是我们想要的结果吗??并且actor模型可以在不加锁的情况下处理并发问题。为什么没有人使用它?并且acotr模型可以使用进程内缓存的形式,远低于请求局域网redis的网络延迟。本文转载自微信公众号《建筑师实践之路》,可通过以下二维码关注。转载本文请联系架构师实践之路公众号
