Solon v3.8.3

graph - 自动化测试与性能调优

</> markdown
2026年1月5日 上午11:15:59

1、自动化测试:如何 Mock 流程环境?

流程编排最怕的是“牵一发而动全身”。为了保证逻辑的健壮性,我们需要针对 Graph 编写单元测试。Solon-Flow 的轻量化设计使得 Mock 测试异常简单。

  • 核心思路:Mock Context

你不需要启动完整的数据库或复杂的中间件,只需要构造一个 FlowContext 即可模拟执行环境。

@Test
public void testOrderFlow() {
    // 1. 获取图定义
    Graph graph = flowEngine.getGraph("order_flow");
    
    // 2. 构造测试上下文,注入 Mock 数据
    FlowContext context =  FlowContext.of();
    context.put("orderAmount", 2000);
    context.put("userLevel", "VIP");

    // 3. 执行评估(执行深度设为 -1 代表全流程执行)
    flowEngine.eval(graph, context);

    // 4. 断言结果
    Assert.assertTrue(context.getAs("isApproved"));
    Assert.assertEquals("Manager", context.getAs("approverRole"));
}

2、性能调优:让大图跑得飞快

当流程图变得极其复杂(例如包含数百个节点或深度嵌套)时,内存与 CPU 的损耗需要精细化管理。

Graph 实例缓存。GraphSpec.create() 涉及大量的索引构建和合法性校验,是一个相对“重”的操作。

  • 错误做法:在每次请求时都 copy 并 create 一个新图。
  • 最佳实践:利用缓存。如果是动态生成的图,建议使用 Map<String, Graph> 或 LRU 缓存,以业务标识为 Key 缓存 Graph 实例。

避免 Context 内存泄漏。FlowContext 在流程运行期间会承载大量数据。

  • 清理机制:流程结束后,确保 Context 对象能被 GC 回收。
  • 数据瘦身:仅在 Context 中存储必要的路由标识和计算结果,大数据对象(如 10MB 的报文)建议存入外部缓存(如 Redis),在 Context 中仅保留 Key。

3、并发治理:线程池的科学配置

之前我们提到了并行网关(Parallel)。在生产中,不合理的线程池配置会导致系统雪崩。如无必要,不使用线程池为好。

隔离策略。建议为不同的 FlowDriver 配置独立的线程池,避免“非核心流程”抢占“核心流程”的线程资源。

FlowDriver driver = SimpleFlowDriver.builder()
                .executor(new ThreadPoolExecutor(
                        16, 32, 60L, TimeUnit.SECONDS, new LinkedBlockingQueue<>(1000)
                ))
                .build();
        
FlowEngine.newInstance(driver);

4、监控与审计:让流程“透明”

在高并发下,如果某个节点卡住,你需要快速定位。

利用 Interceptor 埋点:通过第四篇学到的拦截器,将每个节点的耗时输出到 Prometheus 或日志系统。

链路追踪:将 Solon 的 TraceId 注入 FlowContext,实现跨节点的分布式链路追踪。

5、生产避坑 CheckList

在正式发布前,请对照此表进行最后的检查:

检查项目的建议
循环边界防止死循环检查 Loop 节点是否有明确的终止条件或执行深度限制。
原子性防止并发冲突并行网关下的多个 Task 是否竞争修改同一个 Context 变量?
Bean 依赖防止空指针确保所有 @beanName 对应的组件在容器中均已注册。

结语:逻辑即资产

我们从基础的连线配置,走到了动态编排、影子拦截、高级网关,最后落脚于生产调优。Solon-Flow 不仅仅是一个工具,它更是一种将“乱如麻”的业务代码转化为“清晰资产”的架构思想。