state-demo示例介绍
state-demo示例介绍
本项目用于对qilu-state的示例,给出一个示例的多订单多状态的模拟处理流程,在任意停机,任意关闭服务的情况下,结合qilu-task实现在5分钟内,所有的订单状态都会保持一致.
项目启动
- 执行数据库脚本,sql/ddl.sql 这个sql是mysql语法,如果要其他数据库的,需要转换
- 配置数据源,分别在MockRunner.java和StateSampleRunner.java中,自行修改数据源的连接
- 配置MQ,项目中支付通知和发货通知都是使用MQ进行,配置文件在mock/main/resources/config/conf.properties和state/main/resources/config/conf.properties中
- 部分依赖base的jar包,请关注项目中的settings-hw.xml文件,配置好里面的profile部分,如果还是不行,请看编译
项目访问
假设mock提供同步返回结果,qilu-state可以提供同步接口,如果mock出现异常,qilu-state会返回处理中,接口变成异步.
请求报文如下
POST /state/new/addOrder.do HTTP/1.1
Accept: application/json, text/javascript, */*; q=0.01
Content-Length: 28
Content-Type: application/x-www-form-urlencoded
Host: localhost:18080
name=senvontest1&amount=12.3测试说明
- 该测试方式依赖mock项目提供同步接口,正常情况下,OrderInfo的订单状态会变成5,同步请求成功
- 如果关闭mock项目,同步请求的远程调用会失败,返回处理中,OrderInfo的状态会处于中间状态,后续经过补单轮询任务,再补成成功
状态说明
请根据下面的状态检查相关订单状态一致
| 表名 | 状态 | 说明 |
|---|---|---|
| TB_Order_Info | 购物订单表 | |
| TB_Order_Info | 1-noPay | 处于刚刚发起订单状态,还没有支付 |
| TB_Order_Info | 2-Paying | 处于支付中状态,可能未发起支付,可能已经发起支付在等待支付结果 |
| TB_Order_Info | 6-PayFail | 支付失败状态,终结状态,一定需要关联orderPay的订单状态为支付失败,也一定需要关联applyInfo中type=1的申请的状态为处理失败 |
| TB_Order_Info | 3-Payed | 支付成功状态,还没有创建发货订单 |
| TB_Order_Info | 4-Sending | 发货中状态,可能未发起发货,可能已经发起发货等待发货结果 |
| TB_Order_Info | 5-Success | 订单成功状态,终结状态,代表当前的订单处理完成 |
| - | - | - |
| TB_Order_Pay | - | 订单支付表 |
| TB_Order_Pay | 1-Wait | 处于刚刚创建记录的状态,还没有调用payApply接口 |
| TB_Order_Pay | 2-Processing | 处于支付中状态,可能未发起支付,可能已经发起支付在等待支付结果 |
| TB_Order_Pay | 3-Success | 支付订单通知成功,终结状态 |
| TB_Order_Pay | 4-Fail | 支付订单通知失败,终结状态 |
| - | - | - |
| TB_Order_Goods | - | 订单发货表 |
| TB_Order_Goods | 1-Wait | 处于刚刚创建记录的状态,还没有调用goodsApply接口 |
| TB_Order_Goods | 2-Processing | 处于发货中状态,可能未发起发货,可能已经发起发货在等待发货结果 |
| TB_Order_Goods | 3-Success | 发货订单通知成功,终结状态 |
| TB_Order_Goods | 4-Fail | 发货订单通知失败,终结状态 |
| - | - | - |
| Mock_Apply_Info | - | Mock系统的表,模拟支付请求和发货请求,用type=1为支付订单,type=2为发货订单 |
| Mock_Apply_Info | 1-Wait | 处于刚刚创建记录的状态,还没有处理 |
| Mock_Apply_Info | 2-Processing | 处于处理中 |
| Mock_Apply_Info | 3-Success | 处理成功,终结状态 |
| Mock_Apply_Info | 4-Fail | 处理失败,终结状态 |
项目结构
mock-service-website
mock-service-webiste 是模拟的一个远程http接口,主要模拟了以下接口
| 接口名 | 含义 |
|---|---|
| payApply | 主要用于模拟创建一个支付订单,在state-sample-website中,会发起一个订单支付请求, |
| searchPay | 主要模拟查询一个支付订单,在订单支付请求发起失败,用于后续的补单查询 |
| goodsApply | 主要用于模拟发货请求,在支付完成以后,进行发货操作,发货不允许失败 |
| searchGoods | 用于模拟发货查询接口,在发货失败以后,查询发货状态 |
state-sample-website
state-sample-website,是state-core的主要载体,用于模拟流程的实现.该工程使用一个简单的电商模型进行验证,主要为了验证在使用state-core的过程中,我们想最大程度的提升可靠性.
订单状态如下图

写在最后的话
在很多系统中,有时候不需要大量的并发或者大量的并发可以通过对硬件的扩展完成,但是可靠性的要求不能直接通过硬件解决.通过电商的这个示例,我想和大家探讨的一个问题,如果一套系统对于可靠性要求比较高,是否可以通过类似state-core的机制来实现.
state-core为了规避流程存储和业务存储的一致,完全没有使用存储,可以在某种程度上当成内存级的流程引擎使用.目前所有开源的流程引擎都只具备节点执行.state-core是从状态机角度来看流程,通过状态机的控制,实现执行代码和事务存储的分离,目前来看,粒度最细,所以复杂.
state-core作为框架,规范了编程结构和方式,在使用过程中,并不能降低业务的复杂度,但是在使用state-core的时候,能在保证可靠性的情况下,减少代码量.示例中最大的难点是在于,因为state-core强行把业务操作和事务进行了分离,导致代码相对凌乱,开发人员在开发过程中,很难理解.
纵然流程有千万缺点,流程的一个特性能掩盖所有的缺点----一旦流程被严谨的测试,一套基于流程的系统会超级稳定.state-core本身不是流程,是通过状态的变迁,形成的类似流程的调用.
