用一份 JSON 串起 HTTP / Dubbo / WebService / SQL / 脚本:开源服务编排引擎 service-arrange

写在前面

日常业务里,一个"下单"动作背后往往要调十几个接口:HTTP 主单服务、Dubbo 库存、WebService 老物流、一段 SQL 校验、再加个 Shell 通知脚本。写死在代码里,链路看不清、改动牵一发动全身;换个顺序、加个失败补偿,就得发版。

service-arrange 想解决的就是这件事:把这条调用链画成一张图,导出成一份 DSL(JSON),由引擎负责解析、调度、重试、补偿和追踪。改流程不用改代码,改图就行。

它是什么

一个基于 DSL 的轻量级服务编排(Service Arrangement)引擎 + 可视化编排控制台:

  • 前端画布产出 DSL(JSON)——全系统唯一契约;
  • 后端引擎负责解析 → 调度 → 执行 → 编排(决策 / 循环 / 补偿);
  • 消息驱动(RabbitMQ + Spring Cloud Stream)、MongoDB 存储、ZooKeeper 分布式锁。

定位类比:轻量版工作流引擎,但强调"服务调用"而非"人工审批"。

核心能力

1. DSL 即契约

节点与连线同构(连线本身也是一个 Cell),扁平 cells 数组 + groups 补偿组 + 运行期全局参数。取值表达式统一为 #节点id$jsonpath,支持 #header_$X-Token、#dynamicParams_$idx 等。前端导出与后端解析严格遵循同一份规范(含 11 条校验规则 R1~R11)。

2. 可视化编排控制台(零依赖)

纯 HTML5 + ES5 JavaScript,无框架、无构建、无 npm install,node serve.js 即可跑起来。左侧分类折叠调色板、右键菜单、双击编辑、属性面板分组、连线圆头圆角、历史脏数据自愈,支持导入导出与 DSL 校验。

3. 20 种算子,覆盖主流调用形态

类别算子
外部调用 HTTP、SQL(JDBC 直连)、Dubbo(HTTP 网关泛化)、WebService(SOAP)
脚本 Shell、Jar、Python
内部算子 数据映射、规则转换、数据结果、决策、JSON↔XML 互转、延时
补偿 数据映射补偿、HTTP / Dubbo / WebService 补偿

画布上统一算子节点 node_op,真实类型由 data.opType 延迟解析(CellTypeMapper),新增算子无需改引擎调度代码。

4. 完整的流程治理

Plan 草稿 / 发布 / 停用 + 版本快照;生产可开启发布门禁(require-published,仅已发布 Plan 可运行);运行幂等(X-Idempotency-Key,命中直接返回既有实例);全链路 traceId(TraceFilter → MDC → Inst);单任务超时(RetryRules.timeoutMs 优先,全局兜底);失败按 RetryRules 重试并受退避上限保护;实例取消 / 恢复;GET /health 应用 + Mongo 双探活。

5. 可靠性设计

ZooKeeper 实例级分布式锁保证同一实例串行调度;抢锁失败带次数上限的线性退避重排队,超限强制 ack 丢弃(防消息热点空转);毒消息处理次数上限;循环线次数上限(防条件恒真打满线程);失败走补偿分支,支持补偿强组合实现局部事务回滚。

6. 工程细节

统一返回 {code, msg, data} + @RestControllerAdvice 全局异常(IllegalArgumentException → 400);HTTP / Dubbo / MongoDB 出网超时;Mongo 连接池参数;消费端并发与背压阈值全部可配置。

架构

浏览器 ──REST──▶ web 模块(Inst / Plan / InstQuery / InstLog / Health 控制器
                      + TraceFilter + GlobalExceptionHandler)
                          │
                          ▼
              engine 核心引擎
   DslParser ──▶ Inst(图结构)──▶ TaskInterface(convert) ──▶ Task
        │                                                   │
        │              TaskRunConsumer ◀── TaskProductor ◀──┘
        │                   │
        │             Execute.runProcess(按 cellType 路由到 20 个算子)
        │                   │
        └── TaskResultConsumer(加 ZK 实例锁 → 决策/循环/补偿编排 → 投递下一批)
                          │
        ┌─────────────────┼─────────────────┐
        ▼                 ▼                 ▼
     RabbitMQ          MongoDB          ZooKeeper

技术栈:Java 8+ / Maven 多模块、Spring Boot + Spring Cloud Stream、Spring Data MongoDB、Curator + ZooKeeper、SpEL + 自定义取值表达式、Hutool;前端零依赖静态站点。

快速开始

前置依赖:JDK 8+、Maven、MongoDB(27017)、RabbitMQ(5672)、ZooKeeper(2181)。

# 1. 克隆(Gitee 主仓库 / GitHub 镜像)
git clone https://gitee.com/huangrenhui/service-arrange.git
cd service-arrange

# 2. 构建并启动后端(默认 8082,上下文路径 /servicearrange)
mvn clean package -DskipTests
java -jar backend/web/target/service-arrange.jar

# 3. 启动前端控制台(零依赖,127.0.0.1:5173)
cd frontend && node serve.js

验证服务就绪:

curl http://localhost:8082/servicearrange/health
# {"code":200,"msg":"success","data":{"status":"UP","mongo":"UP"}}

30 秒跑通一条流程

# 1. 保存流程模型(DSL 可从控制台导出,或参考 backend/web/src/main/resources/hrh_http.json)
curl -X POST http://localhost:8082/servicearrange/plan/save \
  -H 'Content-Type: application/json' \
  -d '{"name":"订单链路","dsl":"{...}","remark":"demo"}'

# 2. 发布(生产建议 task.orchestration.require-published: true)
curl -X POST "http://localhost:8082/servicearrange/plan/publish?id=<planId>"

# 3. 运行(幂等键可选,traceId 自动生成)
curl -X POST "http://localhost:8082/servicearrange/inst/run/or/getResult/<planId>?servea_optType=run" \
  -H 'X-Idempotency-Key: order-20261018-001' \
  -H 'Content-Type: application/json' -d '{"orderId":"A1001"}'

# 4. 观察
curl "http://localhost:8082/servicearrange/inst/detail?id=<instId>"          # 实例 + 任务 + 日志
curl "http://localhost:8082/servicearrange/instlog/list?instId=<instId>"     # 节点级日志

共 17 个 REST 接口:流程模型 6 个、运行实例 1 个、实例查询与干预 4 个、实例日志 1 个、算子注册 4 个、健康检查 1 个。

界面一览

控制台共 6 个视图:实例列表、编排设计器、运行记录、运行详情、算子注册、Schema 工具。

实例列表

实例列表展示状态徽标、发布状态与版本、节点数与运行次数,每个实例可直接进入编排 / 发布 / 运行 / 运行记录。

编排设计器是核心:左侧为分类节点库(HTTP / SQL / Shell / 内部算子),画布支持普通线、决策线、循环线、补偿线四种线型,节点可拖拽、右键菜单编辑、属性面板分组配置,顶部工具栏提供导入 / 导出 / 校验 / 保存 / 发布 / 保存并运行。

编排设计器

拖拽节点调整布局

运行记录与运行详情:每次运行生成一条记录;详情页的编排图按结果染色(成功 / 失败 / 跳过 / 运行中 / 未执行),并可下钻到算子级日志。

运行记录运行详情 · 编排图运行详情 · 实例日志

算子注册把外部 API 登记成可复用资产,注册后即可在任意实例的编排页拖拽使用;Schema 工具用于维护开始 / 结束节点的出入参 Schema。

算子注册Schema 工具

点「保存并运行」时,开始节点的 JsonSchema 会自动渲染成运行入参表单:

运行入参

截图取自控制台自带的演示数据(未连接后端),右上角连通性显示 404 属预期现象。

一个完整案例:订单履约链路(带补偿)

流程:开始 → 数据映射(组装入参)→ HTTP 主单 → WebService 物流 → 结束,同时为 HTTP 节点挂接补偿组(补偿数据映射 → HTTP 补偿),任一节点失败即触发补偿回滚。

成功运行:6 个节点全部成功,实例状态 SUCCESS,出参携带物流单号(即上面 04 / 05 两张图)。

失败运行:WebService 物流节点连接超时 → 实例记 ERRO 日志 → 命中补偿线 → 依次执行 HTTP 补偿 / Dubbo 补偿 → 实例置 FAIL,未执行节点置「跳过」:

失败运行 · 实例日志失败运行 · 编排图染色

这就是「局部事务 + 补偿」的落地形态:不引入分布式事务协议,用一张图把回滚动作声明出来,失败路径与成功路径同样可观测。

文档

仓库内置 17 篇文档,从入门到运维全覆盖:快速开始、项目总览、DSL 规范(唯一契约)、执行引擎与调度流程、数据模型与消息模型、REST 接口说明、企业编排能力、算子扩展指南、前端控制台说明、配置说明、部署指南、测试指南、系统架构、编码规范、功能清单、项目现状、文档说明。入口从 docs/文档说明.md 开始,按角色给了最短阅读路径。

仓库地址

License:GPL-3.0。

结语

如果你也在为"散落各处的服务调用怎么串成一条可观测、可重试、可补偿的链路"头疼,可以拿它当一个轻量起点:DSL 契约清晰、算子可插拔、控制台零依赖开箱即用,文档把每个设计决策和实现差距都写清楚了。欢迎 Star / Issue / PR。

posted @ 2026-10-18 12:46  码猿手  阅读(80)  评论(2)    收藏  举报
Live2D