程序员修神之路--有状态的服务其实可以做更多的事情 (2)

有状态的服务本质上是一些有状态对象的集合,这些对象状态的变化只发生在当前服务进程中

优势和劣势

程序员修神之路--有状态的服务其实可以做更多的事情

有状态服务之所以被称为有状态,一个很大的原因是它可以追溯状态的变化过程,也就是说一个有状态的服务保存着状态变化的记录,并可以根据这些历史记录恢复到指定的状态,这在很多场景下非常有用。举一个很简单的栗子:我们平时玩的斗地主游戏,三个玩家,当有一个玩家因为网络原因掉线,经过一段时间,这个玩家又重新上线,需要根据某些记录来恢复玩家掉线期间系统自动出牌的记录,这些出牌记录在这个业务中其实就是这个玩家的状态变化记录。在有状态的服务中,很容易做到这一点。

其实实际开发中很多场景不需要记录每个状态的变化,只保留最新状态即可,不单单是因为保存每个状态的变化需要大量的存储和架构设计,更因为是很多业务根本不需要这些状态变化记录,业务需要的只是最新的状态,所以大部分有状态的服务只保存着最新的状态。

有状态的服务在设计难度上比无状态的服务要大很多,不仅仅是因为开发设计人员需要更好的抽象能力,更多的是一致性的设计问题。现代的分布式系统,都是由多个服务器组成一个集群来对外提供服务,当一个对象在服务器A产生之后,如果请求被分配到了服务器B上,这种情况下有状态的服务毫无意义,为什么呢?当一个相同的业务对象存在于不同的服务器上的时候,本质上就违背了现实世界的规则,你能说一个人,即出生在中国,又出生在美国吗? 所以有状态的服务对于一致性问题有着天然的要求,这种思想和微服务设计理想不谋而合,举个栗子:一个用户信息的服务,对外提供查询修改能力,凡是用户信息的业务必须通过这个服务来实现。同理,一个对象状态的查询修改以及这个对象的行为,必须由这个对象的服务来完成。

程序员修神之路--有状态的服务其实可以做更多的事情

有状态的服务要求相同业务对象的请求必须被路由到同一个服务进程。

程序员修神之路--有状态的服务其实可以做更多的事情

因此,有状态的服务对于同一个对象的横向扩容是做不到的,就算是做的到,多个相同对象之间的状态同步工作也必然会花费更多的资源。在很多场景下,有状态的服务要注意热点问题,例如最常见的秒杀,这里并非是说有状态服务不适合大并发的场景,反而在高并发的场景下,有状态的服务往往表现的比无状态服务更加出色。

Actor模型



程序员修神之路--有状态的服务其实可以做更多的事情

在众多的并发模型中,最适合有状态服务设计的莫过于Actor模型了,如果你对actor模型还不熟悉,可以撸一遍菜菜之前的文章:https://mp.weixin.qq.com/s/eEiypRysw5jsC7iYUp_yAg  actor模型天生就具备了一致性这种特点,让我们在对业务进行抽象的时候,不必考虑一致性的问题,而且每一个请求都是异步模式,在对象内部修改对象的状态不必加锁,这在传统的架构中是做不到的。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/zzjgjg.html