分布式系统中的“无状态”和“有状态”

无状态

无状态的好处?
客户端请求不依赖服务端的信息,任何多次请求不需要必须访问到同一台服务
服务端的集群和状态对客户端透明 =-服务端可以任意的迁移和伸缩 =-减小服务端存储压力
什么是有状态?
有状态服务,即服务端需要记录每次会话的客户端信息,从而识别客户端身份,根据用户身份进行请求的处理,典型的设计如 tomcat 中的 session。

例如登录:用户登录后,我们把登录者的信息保存在服务端 session 中,并且给用户一个 cookie 值,记录对应的 session。然后下次请求,用户携带 cookie 值来,我们就能识别到对应 session,从而找到用户的信息。

有状态

什么是有状态?
有状态服务,即服务端需要记录每次会话的客户端信息,从而识别客户端身份,根据用户身份进行请求的处理,典型的设计如 tomcat 中的 session。

例如登录:用户登录后,我们把登录者的信息保存在服务端 session 中,并且给用户一个 cookie 值,记录对应的 session。然后下次请求,用户携带 cookie 值来,我们就能识别到对应 session,从而找到用户的信息。

有状态的缺点是什么?
• 服务端保存大量数据,增加服务端压力
• 服务端保存用户状态,无法进行水平扩展
• 客户端请求依赖服务端,多次请求必须访问同一台服务器

状态化的判断是指两个来自相同发起者的请求在服务器端是否具备上下文关系。

如果是状态化请求,那么服务器端一般都要保存请求的相关信息,每个请求可以默认地使用以前的请求信息。

而无状态的请求,服务器端的处理信息必须全部来自于请求所携带的信息以及可以被所有请求所使用的公共信息。

无状态的服务器程序,最著名的就是WEB服务器。

状态化的服务器有更广阔的应用范围,比如MSN、网络游戏等服务器。他在服务端维护每个连接的状态信息,服务端在接收到每个连接的发送的请求时,可以从本地存储的信息来重现上下文关系。

纯函数式编程,就是无状态的。有状态,也叫有副作用。
无状态的服务易伸缩: 很容易的通过给后端添加服务器和前端的负载均衡实现横向的扩展。
当系统中存在着大量「有状态」的业务处理过程时,伸缩扩展就会变得复杂起来。

从单机服务到集群化

构建单机服务非常简单,但如果单机服务可靠性或性能不足,就需要多机器共同承担某项服务。集群化包含以下三种情况:

无状态主备集群
仅有一台主机完成任务,且没有本地状态,其余从机机器待命,一旦主机宕机,从机选主成为主机。

有状态主备集群
仅有一台主机完成任务,有本地状态,其余从机机器待命,一旦主机宕机,从机选主成为主机。

无状态的主从集群
所有机器没有本地状态,理论上机器可以无限叠加,共同向外界提供同一服务。解决方案就是dubbo+zookeeper。

有状态的主从集群:
所有机器都有本地状态,共同向外界提供同一服务。一旦某台机器宕机,需要主机协调其他从机代理其本地状态的任务。Paxos、raft和ZAB等一众分布式一致性算法的终极目标就是解决该问题。

总结

有状态服务需要维护大量的信息和状态,在性能方面要稍逊于无状态服务器;
无状态服务在处理简单服务方面有优势,服务之间没有联系,易于扩展,但处理复杂任务需要额外的组件来协助(以有状态服务的形式实现)。
微服务要尽量做到无状态,这样可以横向扩展。
状态服务原则并不是说在微服务架构里就不允许存在状态,表达的真实意思是要把有状态的业务服务改变为无状态的计算类服务,那么状态数据也就相应的迁移到对应的 “有状态数据服务” 中。

简单举例

例如我们以前在本地内存中建立的数据缓存、Session 缓存,到现在的微服务架构中就应该把这些数据迁移到分布式缓存中存储,让业务服务变成一个无状态的计算节点。迁移后,就可以做到按需动态伸缩,微服务应用在运行时动态增删节点,就不再需要考虑缓存数据如何同步的问题。

你可能感兴趣的:(springCloud,1024程序员节,有状态,无状态)