在系统设计时,如果能预先看到一些问题,并在设计层面提前解决,就会给后期的开发带来很大的便捷。相反,有缺陷的架构设计可能会导致后期的开发工作十分艰难,甚至会造成“推倒重来”的情形。因此,在系统设计阶段,应该尽可能的规避项目开发中可能会遇到的各种问题。本文就选取了几个经典的问题进行介绍。
Session共享问题
在Web项目中,Session是服务端用于保存客户端信息的重要对象。单系统中的Session对象可以直接保存在内存中,但在分布式或集群环境下,多个不同的节点就要采取措施来共享Session对象,具体可以使用以下几种方式。
1.Session Replication
SessionReplication是指在客户端第一次发出请求后,处理该请求的服务端就会创建一个与之对应的Session对象,用于保存客户端的状态信息,之后为了让其他服务端也能保存一份此Session对象,就需要将此Session对象在各个服务端节点之间进行同步,如图1所示。
图1 Session Replication
SessionReplication的这种Session同步机制虽然能够使所有的服务节点都拥有一份Session对象,但缺点也是很明显的,如下所示。
(1)容易引起广播风暴。试想,如果有50个服务节点,那么当一个节点产生了Session对象后,就需要将该Session对象同步到其他49个节点中,因此会增大网络的开销。
(2)会造成严重的冗余。如果有多个用户同时在访问,那么每个服务节点中都会保存多个用户的Session对象。可以发现,服务节点的个数越多,Session冗余的问题就越严重。因此Session Replication方式只适用于服务节点较少的场景。
2.Session Sticky
Session Sticky是通过Nginx等负载均衡工具对各个用户进行标记(例如对Cookie标记),使每个用户在经过负载均衡工具后都请求固定的服务节点,如图2所示。
图2 Session Sticky
客户端A的所有请求都被Nginx转发到了应用服务X上,客户端B的所有请求都被转发到了应用服务Y上,因此各个服务中的Session就无需同步。但此种做法也有严重的弊端:如果某个服务节点宕机,那么该节点上的所有Session对象都会丢失。
3.独立Session服务器
除了Session Replication和Session Sticky两种方式以外,还可以将系统中所有的Session对象都存放到一个独立的Session服务中,之后各个应用服务再分别从这个Session服务中获取需要的Session对象,如图3所示。在大规模分布式系统中,就推荐使用这种独立Session服务方式。并且这种方式在存储Session对象时,既可以用数据库,也可以使用各种分布式或集群存储系统。
图3 独立Session服务器
优先考虑无状态服务
在使用了“独立Session服务器”之后,应用服务就是一种“无状态服务”,换句话说,此时的应用服务与用户的状态是无关的。例如,无论是哪个用户在什么时间发出的请求,所有的应用服务都会进行完全相同的处理:先从Session服务中获取Session对象,再进行相同的业务处理。
读者也可以从“有状态服务”来对比理解“无状态服务”。“有状态服务”是指不同的应用服务与用户的状态有着密切的关系。例如,假设应用服务A中保存着用户Session,应用服务B中没有保存。之后,如果用户发出一个请求,经过ngnix转发到了应用服务A中,那么就可以直接进行下单、结算等业务;而如果用户的请求被ngnix转发到了应用服务B中,就会提示用户“请先登陆……”。类似这种,不同应用服务因为对用户状态的持有情况不同,从而导致的执行方式不同,就可以理解为“有状态服务”。
总的来讲,“无状态服务”有很多优势,如下所示。
1.数据同步。
“有状态服务”为了在不同的服务节点之间共享数据,必然会进行数据同步,而不同节点之间的数据同步又会带来CPU/内存损耗、网络延迟、数据冗余等问题;而“无状态服务”不需要数据同步;
2.快速部署。
如果系统的压力太大,就需要增加新的服务节点,从而对系统扩容。如果采用的是“有状态服务”,就需要在扩容后先将其他服务节点上的Session等信息同步到新节点上;而如果采用的是“无状态服务”,就不必同步。可以发现,快速部署的优势本质上也归功于“数据同步”。
实际上,我们这里介绍的“状态”不仅仅是Session,也可以是任意类型的数据、结构化数据、非结构化数据、文件等。因此,要想真正的实现应用服务的“无状态”,就需要先将各种类型的“状态”各自集中存储,具体存储方式如下。
(1)Session等保存在内存中的数据:构建独立的服务,如Session服务。
(2)结构化数据:MySQL等关系型数据库。
(3)非结构化数据:
·适合存储非结构化数据的数据库,如HBase等;
·如果是海量的“状态”,也可以存储在ElasticSearch等搜索引擎中。
(4)文件:
·独立文件服务器,如HDFS、FastDFS等
·CDN。
以上的对应关系,如图4所示。