自动化场景业务的设计

乐云一
  • 业务
  • 业务
About 2326 wordsAbout 8 min

自动化场景业务理解

最近接触到自动化场景,指设定好场景的触发条件以及执行目标指令,当条件通过成功时自动触发其业务。是一个比较复杂且细节繁多的设计,因为里面要考虑到非常多:并发、内循环、缓存压力、启动标识、结束标识、场景日志等等等等问题。所以结合本人当前的技术与业务水平,念叨叨一下

何为自动化

根据条件执行场景

用户通知系统:“我”要执行的目标 , 什么条件下才执行这个目标。

条件

自动化的条件大致分为三个

  • 时间:延时、当前
  • 某个目标值的比较:大于、小于、大于等于、小于等于、等于、包含
  • 前置动作判断:另一个动作的开始或结束、某个标识的变动、地球值或系统值变化[天气、CPU占用等...]

并且由于条件一个或多个 条件的判断上也会有如下三种:

  • 一个满足
  • 指定的某几个满足
  • 全都满足

所以我们需要设计三个强大的条件引擎,满足条件判断的同时,外置一个处理器去判断所有条件的结果是否通过本次执行设置。

动作

动作大致分为两个

  • 执行一个业务、目标值
  • 执行另一个场景

在自动化执行动作中,会涉及到一个非常非常难解决的问题,内循环执行问题。

产生条件:

  • 场景套娃,场景A执行场景B,场景B执行场景C,场景C执行场景A
  • 指令 — 条件套娃,场景A的执行指令,是场景B的执行条件;场景B的执行指令,是场景A的执行条件

由于条件与执行动作的多样性,并且每个条件、场景,的运行区域都不是在一个链路的线程上的。

所以导致即使是一个很简单的场景套娃:

如果在一个线程链路中,只要用一个Set存入每个场景的标识,在这个链路中每个场景执行前,判断一下Set中是否已存在当前场景标识,如果存在则结束链路

但执行引擎运行时,每个场景的运行区域都是互相隔离的,无法做到简单的通信。 emo

技术难点

想这个业务场景的方案时,发现每想一个点,都会出现一个不好处理的问题。

这些问题或多或少,如果处理不当,都是造成整个程序,第三方组件数据库、缓存、微服务等的崩溃 emo

时间段条件

如果场景的执行条件是,某周、某日的某个时间段

对于系统而言,必须创建一个每X秒去循环遍历 存在时间条件的场景 ,然后去判断:

  • 符合,那么判断这个场景是否还有其他条件,如果没有则执行
  • 不符合

所以我们要重点关注的是,每X秒存在时间条件的场景 这两个问题

每X秒

这个时间不能很频繁,也不能很长;

并且,一定一定不能设置在边缘时间范围:比如 1-5秒,55-59秒这样子。

不然对于用户体验是很糟糕的,因为常有用户需要进行自动化场景的测试,那么在当前时间的边缘时间时开启自动化场景。

当时由于遍历时间的问题,导致当前时间的这一分钟并不符合条件。

存在时间条件的场景

首先,一定纯做DB动作。

因为对于一个系统的稳定性来说,我们不能对这种未知大小的数据表进行一次次的DB操作。

所以我们必须定义一个合理的Key-zset值,比如:

将时间分为12段,每两小时一段作为一个key值,

当场景设置条件为时间时,则判断这个时间在哪个时间片中,将其场景对象存入对应的时间片缓存中。

延时执行

延时执行根据场景的设置有两种方式:

  • 该场景延时场景
  • 该场景中的某个指令,一个延时时间后,执行下一个动作

所以我们需要一个可靠的manager去管理场景发送 延时时间-动作

这里推荐直接使用 RabbitMq的延时插件:

https://github.com/rabbitmq/rabbitmq-delayed-message-exchange/releasesopen in new window

然后根据以上两种方式,去控制发送的message,走不同的业务链路

内循环

首先造成内循环的原因上面提到过,主要有两种情况考虑:

  • 指令-条件循环
  • 场景循环

第一种解决方案想到过一个大概,但是仔细考虑又感觉会影响到用户使用体验

第二种解决方案很不靠谱。

但因想到,如果扼制住内循环的链路,肯定会影响到用户使用,因为:

如果用户不知道自己设置了内循环,但是需要这个场景执行,但由于内循环处理并不会执行

第一种

将每次场景执行往后的指令,通过

key:场景标识+指令标识+指令值+场景区域

存入缓存中

那么每个场景的条件判断前,先判断这个条件是否是 另一个场景的指令条件

key:场景标识+[指令对应条件]标识+条件值+场景区域

并且根据条件的判断类型:大于、小于、等于、大于小于.....

去判断该指令条件的值是否符合当前场景的条件

如果符合,则终止操作。

问题: 缓存的压力 ,难度【条件判断类型】,样式太多

第二种

将执行过的场景标识存入缓存中,

key:场景标识
value:时间戳

当执行场景时,去缓存中判断,这个场景的最后时间戳时间,如果相隔近,则终止;

# 推荐:
内循环场景创建前,去提示用户,内循环问题

所以需要在创建场景前,通过遍历指令,与对应条件,

写一个深度DFS去check内循环合法性,并且通知用户是否创建

开启标识

什么时候开始这个场景的条件判断

  • 当条件值变动时
  • 设置一个n秒循环

对于地球值、系统值的条件,我们只能创建一个n秒循环,然后去遍历有这个条件的场景,然后走条件引擎-》规则引擎链路

对于条件值变动的条件,则需要写一个能包容所有条件值判断的规则引擎 emo

并发

一个场景开始判断条件->执行->执行解决,下发日志

是不可控时间的,所以当场景执行时,

对于用户来说,应该是可以修改的;

但是基于一个业务的原子性来说,我们是很不希望用户进行修改操作。

所以有考虑到几个方案去控制:

  • 开始判断条件时,拷贝一份当前版本的场景镜像存入缓存
  • 修改场景操作,与执行动作同步,只有当场景的执行动作整个链路完成,修改场景操作的事务才上交
  • ...

缓存的访问、事务压力

在条件判断、执行、修改等等动作中,都会存在访问同一个key的情况

并且由于场景值的变动,第三方业务的影响等等;

需要做 取Key,修改Value,覆盖原Key的操作。

这样就会导致缓存的事务需要频繁的控制

很影响热点时段、热点条件符合时的场景访问缓存的需求

总结

是一个挺有意思的业务,时间有空的兄弟可以去试着开发一个自动化场景;

在未考虑细节前:内循环、并发、缓存、key值设置问题等等

但随着开发的进行,也就会发现细节中暴露出的各个问题。 emo

Last update:
Contributors: leyunone
Comments
  • Latest
  • Oldest
  • Hottest
Powered by Waline v2.14.7