我计划使用 Spring 状态机来控制执行工作流程。系统预计会接收来自多个用户的请求,并且每个用户可能会被分配到多个工作流程。我最初的想法是每个工作流程都有一个 SM 实例,每次用户在工作流程中执行一个步骤时,我都会使用其标识符从持久存储中恢复机器,输入新事件并存储更新的 SM。
我读到过,初始化 SM 是一项昂贵的操作,有些人建议使用它的单个实例,但用一些数据“补充”该实例。我的理解是,这会更有效,但我认为这会成为一种“阻塞”操作,换句话说,一个工作流程需要等待前一个工作流程完成/提前发布。由于我是这个主题的新手,任何人都可以阐明我的用例的最佳替代方案,也许还有一些代码来说明差异? (PS:我使用的是v2.4.0)
最佳答案
我首先实现了“补充”机制,因为正如你所说,它很有意义,并且也被用在 spring-statemachine 的“持久”示例中。
但是,针对我的 API 运行性能测试表明,当使用 StateMachine 作为 @Autowired
时,使用单个实例会失败。 bean 与prototype
范围如该示例中所述。发生的情况是,针对我的 API 的同时请求会覆盖该状态机 Bean,并且当写回数据库时状态机发生变化时,第一个请求会失败(我使用了 redis)。
所以现在我实际上每次收到请求时都会构建一个新的状态机并重新水化该对象:
public String getStatesGuest(HttpServletRequest httpServletRequest) throws Exception {
StateMachine<States, Events> stateMachine = stateMachineConfig.stateMachine();
resetStateMachineFromStore(httpServletRequest.getSession().getId(), stateMachine);
return convertToJson(buildGetStateResponse(stateMachine));
}
它仍然非常高效,我以大约 30 个请求/秒进行测试,并且仍然得到 12 毫秒的中位数。 (Docker 有 2 个核心用于 spring boot,1 个核心用于 redis)。
关于java - 恢复 Spring State Machine 实例时的推荐方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/68290333/