在当下很多的应用场景中,我们常常会想要应用具有一定的灵活性,以便我们可以在线调整计算逻辑,而不需要重新发布应用。这可能也可以称为以极限的速度发布软件的方式。
AB测试
可以说解决了一部分这样的需求,使得我们可以在线的针对部分用户改变应用的行为。但AB测试
需要我们预先定义并实现两套逻辑,然后通过线上配置来应用不同的逻辑。显然,在可自定义的程度上,AB测试
是非常弱的。如果我们想要更大规模的调整应用的逻辑,AB测试
就不够了。
除了AB测试
,有另一种大家能很容易想到的实现方式,那就是支持线上脚本。我们可以设计一个管理员功能,以便管理员可以上传代码,或者在线编辑代码,然后应用可以将这样的代码动态的应用到程序里面。为了方便的编写代码,通常这样的线上脚本语言会以更容易编写也更简洁的Groovy
Scala
或者Python
JavaScript
。
自定义脚本的方式虽然比AB测试
更自由灵活,理论上可以实现任何功能。但是如果我们大量采用这样的方式来自定义程序功能,带来的弊端也是显而易见的,比如:
- 程序可能没有经过完善测试就被应用到了线上,从而带来更多的潜在bug和不稳定性
- 脚本的版本管理可能更难以实施
- 可能导致功能被滥用,而导致代码越来越难以管理
在实践中,我们常常要较好的平衡这样的动态脚本的功能范围,才能发挥好它应有的作用。
事实上,可能还有另一种处于AB测试和自定义脚本的中间实现方式。
工作流应用
在最近的一个项目上我有机会调研了一下比较传统的工作流应用。工作流应用的典型场景是在企业管理流程数字化领域。比如,对于一个请假流程,可能的流程是:1. 提交请假原因时间等信息;2. 部门领导审批;3. 人事部门审批;4. 请假结束销假。我们当然可以很容易的针对这样的流程实现一个请假应用。但是在另一个企业中,请假流程可能变为:1. 提交请假原因时间等信息;2. 给相关人员发邮件;3. 请假结束销假。我们难道要为每一个企业单独定制一种请假应用?工作流应用就是应用在这样的场景中,期望以一种低代码的方式快速定制出各个公司所需要的不同的工作流程。
早在20年前这个问题就开始被大家研究了。BPMI(The Business Process Management Initiative)曾经开发了一套标准叫业务流程建模符号(BPMN - Business Process Modeling Notation)。经过超两年的努力,于2004年5月对外发布了BPMN 1.0 规范。后BPMI并入到OMG组织,并于2011年推出BPMN2.0。很多商业公司实现了这个标准,并提供了相应的可视化流程设计器,我们只需要用这个设计器设计流程并编写少量的代码就能实现各种不同的企业应用了。这无疑大大推进了企业的数字化进程。
当前最流行的开源工作流引擎要算activiti
了,它是由Alfresco公司开发,以Apache license
授权在GitHub
开源。使用activiti
,要完成上述请假流程,我们首先用基于网页或者eclipse
插件的流程设计器设计流程(包括可以分派给某人的流程任务和程序自动化完成的任务),导出bpmn2
的流程配置文件,然后对于请假申请表单,审批表单等,可以用表单设计器设计相应的表单,最后根据需求进行一定的定制就可以完成了。以下几张截图可以让大家体会这个过程。
为了支持更完善的功能,activiti
在bpmn2
标准的基础上添加了很多的功能,比如基于事件处理器的机制,定时器机制,异常处理机制,数据库事务支持,发邮件,WebService
集成支持等等。通过并行网关或者排他网关(相当于条件控制器),流程设计器还可以支持非常复杂的流程控制。
对于这类工作流应用,大家褒贬不一,反对意见主要在于:
- 一旦我们过于依赖工作流应用,我们的代码逻辑可能会以众多脚本的形式分散到配置文件中,难以建立单元测试来保证程序功能;
- 难以从领域角度进行有效的建模,当流程过于复杂之后,这种基于流程和数据的架构难以支持应用的演进;
- 流程之间的数据传输基于无模型抽象的字典,一旦状态多了,程序会更难以理解和不好调试。
总之要想发挥工作流应用的最大效果,我们需要平衡好抽象的粒度,需要梳理好哪些流程要交给代码完成(代码天生用于实现复杂流程控制),哪些交给工作流应用。
极速发布的实现
既然工作流应用对于流程定义有相对完善的支持,那么理论上可以用它来实现任意的程序功能。除了用于建模企业工作流程,是不是可以拿来解决文章开始提到的在线调整程序逻辑的功能呢?
为了实现这一功能,我们可以将应用服务API
作为可供工作流服务任务(Service Task,程序自动化任务)调用的API
提供出来,然后通过工作流设计器组装各种服务任务来完成一定的程序功能(也可以称作服务编排)。这样一来,我们不仅可以通过工作流设计来灵活的在线调整程序功能,也不至于使得工作流被设计得过于复杂。
在一些业务不确定性比较强的应用场景中这种工作方式可能是合适的。比如在银行风控领域,我们期望有一个API
能评估某一用户的贷款申请的风险,这个API
的实现会非常复杂而充满不确定性,而且我们期望它能比较灵活的支持在线逻辑调整。因为在实现这个API
时我们需要综合考虑很多情况,比如失信名单,贷款金额,历史信用得分,不同的机器学习模型分析结果,不同模型的效果对比,模型陪跑测试等等。如果能有一个支持上述工作流级别的灵活的在线逻辑调整的功能就好了。
我们是不是可以用activiti
来实现这样的功能呢?当然是可以的,但是传统的工作流应用可能并不合适,因为它并不是为支持这种场景而设计的,比如传统的工作流应用会持久化每一个流程的状态,以便可以支持一些用时很长的需要用户完成的任务。传统的工作流应用在这种场景下的一个重要的缺点就是性能太低,因为它支持了太多其他用不到的功能。在我的测试中,对于一个非常简单的自动化流程,activiti
也需要80ms左右才能运行完成。
于是,我们需要一个高性能的自动化工作流引擎。为了缓解这一问题,我用node
实现了一个这样的工作流引擎,该工作流引擎可以以微服务的形式发布出来,如无必要我们无需改动内部实现。使用与上面类似的一个工作流进行性能测试,95%的API
响应时间在10ms以内,99%的API
响应时间在20ms以内,单node
进程可以支持1000左右的rps。
为了使得我们可以独立的用activiti-modeler
进行流程设计,我对开源的activiti-modeler
进行了一定的修改,移除了权限管理的模块,并预置了一些模板流程数据供大家参考。
尝试体验这个微服务很简单,我已经将应用部署到了heroku
,大家只需要:
- 打开网页
https://node-bpm-modeler.herokuapp.com/
进行流程设计(由于没有后端API
支持,所有的持久化相关的功能均不可用) - 打开网页
https://node-bpm.herokuapp.com/
将设计好的流程文件(BPMN 2.0 XML)格式填入,并定义好流程处理器代码,然后运行测试
参考下图:
这个简单的工作流引擎开源在GitHub
上面这里,大家如有兴趣,欢迎一起参与实现更多功能。如果有场景可以用到这个微服务,也欢迎大家进行尝试。