多条件状态机设计


前言

提示:本文设计了一套针对复杂场景下的状态机服务,支持从多种事件触发,做状态的正确流转

状态机服务在很多系统中都是很重要的,经常用来管理业务实体的状态,需要从各个业务线、系统的事件消息中计算出业务实体的状态值。状态机往往被设计成一个独立的服务,基于事件驱动,设计目标往往是准确、健壮、可扩展和高性能。
如何设计出这一套状态机呢,个人认为具体应用场景有具体应对的技术方案,简单的、复杂的都有。本文在实际项目中针对状态机就设计了一个多版本状态机的技术方案。


一、多版本状态机名词解释

这是个人想出来的一个名词,简单来说就是状态机中的状态(相同的ID)具备不同的版本。状态机中的状态不一定是完全唯一不重复的,可能存在随着外部环境的变化出现相同状态但是有不同的版本,类似于数据的版本。比如一台设备在线了,都是在线状态,但是设备先通过tcp连上了服务器,后来通过ota升级通过websocket连上服务器。此时设备都是在线状态,但是在线方式不一样,因此在线状态的版本也不一样。

二、多版本状态机解决了什么问题

通过使用状态版本,多版本状态机可以解决状态爆炸的问题。就比如刚才举例的设备在线状态,设备通过不同的方式连上服务器来保持在线状态,这会产生两个event事件,而且这两种方式不共存,因此会分别对应不同的在线状态。随着类似这样的规则变多,最终状态机中的状态会越来越多,最终造成状态机服务状态爆炸。直观些来说,其实设备的状态都是在线,只是随着设备版本,产生的来源(event)不同。因此,针对状态增加版本的设计就是显而易见的。

三、如何设计多版本状态机

了解了多版本状态机的设计目的,具体设计起来就很容易了。可以在状态机规则计算时考虑进版本的概念。比如:
源状态可以通过不同的event跳转到相同状态的不同版本
结构化规则数据类似:
在这里插入图片描述
通过多版本的概念,可以做单版本内状态流转的闭环,同时也支持多版本间状态集合的跳转。具体可以根据不同的业务场景进行设计,比如:
a. 限制状态在单版本内跳转做到版本级别隔离场景
限制状态在单版本内跳转做到版本级别隔离
b. 状态在多版本内根据情况跳转场景,做到按需扩展
在这里插入图片描述

四、多版本状态机状态定时触发逻辑

由于引入了状态版本的概念,整体的状态总数会多,因此状态的定时触发逻辑需要处理的数据量就会显著增加。因此,需要针对状态定时触发逻辑进行优化设计。这是几点需要考虑的:
首先,在数据库选型上,由于定时触发跟时间有强相关性,在数据量不大的场景,通过时序数据库存储状态是最为合适的。但是数据量超大的场景(时序数据库时间线有限),只能使用分布式数据库存储数据,通过分区表或者分库分表的方式存储数据。这需要从功能和成本上进行考虑

请添加图片描述
其次,在状态记录存储上,大部分情况下是通过log形式append,少部分是在固定的维度上通过upsert的方式记录最新的状态即可。这两种方式各有所长,在数据库存储层面上通过log append的方式进行记录,在不增加DML次数的情况下,减少了对索引的update,同时可以记录状态的变化情况。在缓存层面上通过upsert的方式记录最新的状态。
请添加图片描述
然后,定时触发任务时,通过database scan的方式查询出符合触发条件的log entry即可。为了提高查询效率,通常在设计log entry时需要考虑trigger time和triggered字段用来保障状态的定时触发逻辑的准确性。

总结

本文简单整理了多版本状态机的设计思路来解决状态机状态爆炸问题,供大家参考,有补充的问题欢迎各位留言。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

baidu_26507163

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值