系列定位 :jeeflow 系列第 9 篇(第三季「多语言联邦」第 1 篇) 平台 :公众号 / 掘金(实用向:一键部署 + 选型) 素材版本 :引擎 Java 1.8.18 / Go·Python·Node 1.8.20 / PHP 1.3.5 / Rust 1.0.5;一键部署脚本取自 mldong-website 前置阅读 :第 8 篇 · 会签三兄弟:并行/串行/按比例的实现与取舍
一、先上结果
在任意一台装了 Docker 的 Linux 服务器上,执行一条命令:
bash
curl -fsSL https://www.mldong.com/deploy/mldong-boot3-jeeflow/deploy.sh | bash
几分钟后(拉镜像 + 灌种子数据),你会得到一套完整可点的工作流应用:
- 管理后台前端:登录、用户/角色/部门、字典、流程设计器、发起/审批/会签/抄送全流程
- 后端 API:jeeflow 工作流引擎接在一个快速开发框架上
- MySQL :预装好的库,含演示账号和 9 个开箱即用的业务流程(请假、报销、采购、合同审批、用印申请、加班、出差、资产领用、岗位异动),每个流程都带版本历史------改一版定义旧版还在,可追溯可回退
- 登录 :
superAdmin / 123456
下面四张截图全部来自 Rust 栈 ------就是刚上线的那条 curl,在一台 2 核 1.7G 的服务器上跑的:




同一台服务器最多可以同时起 8 套,互不冲突。因为这套"一键部署"不是只有一种语言------六语言、八栈,各一条命令:
bash
curl -fsSL https://www.mldong.com/deploy/mldong-boot4-jeeflow/deploy.sh | bash # Java · Spring Boot 4(JDK 21)
curl -fsSL https://www.mldong.com/deploy/mldong-boot3-jeeflow/deploy.sh | bash # Java · Spring Boot 3(JDK 17)
curl -fsSL https://www.mldong.com/deploy/mldong-boot2-jeeflow/deploy.sh | bash # Java · Spring Boot 2(JDK 8)
curl -fsSL https://www.mldong.com/deploy/mldong-goframe-jeeflow/deploy.sh | bash # Go · GoFrame
curl -fsSL https://www.mldong.com/deploy/mldong-nestjs-jeeflow/deploy.sh | bash # Node.js · NestJS
curl -fsSL https://www.mldong.com/deploy/mldong-fastapi-jeeflow/deploy.sh | bash # Python · FastAPI
curl -fsSL https://www.mldong.com/deploy/mldong-laravel-jeeflow/deploy.sh | bash # PHP · Laravel
curl -fsSL https://www.mldong.com/deploy/mldong-salvo-jeeflow/deploy.sh | bash # Rust · Salvo
六语言引擎:Java / Go / Python / Node.js / PHP / Rust 。Rust 栈是本周刚上线的------引擎本周在 crates.io 首发(cargo add jeeflow-core@1.0.5),集成仓当天完成验收,一键部署区同步开了 Rust Tab。
你是哪门语言,就选哪条。
二、怎么选?
八栈对比(全部已验证可部署):
| 栈 | 语言/框架 | 运行时 | 引擎版本 | 适合 |
|---|---|---|---|---|
| boot4 | Java · Spring Boot 4 | JDK 21 | 1.8.18 | 新建 Java 项目,要最新框架 |
| boot3 | Java · Spring Boot 3 | JDK 17 | 1.8.18 | 主流 Java 项目(大多数团队的默认) |
| boot2 | Java · Spring Boot 2 | JDK 8 | 1.8.18 | 存量 SB2 / JDK 8 项目(还在 8 上的不少) |
| goframe | Go · GoFrame | --- | 1.8.20 | Go 服务、单二进制部署、高并发 |
| nestjs | Node.js · NestJS | --- | 1.8.20 | 全栈 JS 团队、同构/BFF |
| fastapi | Python · FastAPI | --- | 1.8.20 | Python 团队、数据/脚本场景 |
| laravel | PHP · Laravel | PHP 8.4 | 1.3.5 | PHP 存量项目 |
| salvo | Rust · Salvo | Rust 1.97 | 1.0.5(本周 crates.io 首发) | 内存安全/高性能诉求,欢迎来踩坑反馈 |
三个说明:
- Java 一个引擎顶三栈:Spring Boot 2/3/4 的框架层不同,底下是同一个 jeeflow-java 引擎,行为一致。选哪个看你 JDK 用哪个。
- 各语言引擎版本号不同是正常的 :Java/Go/Python/Node 走
1.8.x,PHP 独立里程碑(1.3.x),Rust 新成员从1.0.x起步。对齐的是同一批契约行为(状态机、提交类型、接口约定),不是同一个版本号------各语言各自发版,不用互相等。 - Rust 栈是第一个:引擎 4 个 crate 刚上 crates.io,集成栈刚并入八栈,属于"首发可用"状态。用的人少,问题反馈价值最高。
三、为什么六语言是卖点,而不是"炫技"
如果你只用一门语言,"六语言"听着确实像自嗨。它的实际价值是三句人话:
1. 流程数据不绑语言(无锁定)
jeeflow 引擎的持久化契约只有 5 张表 :wf_process_define / wf_process_instance / wf_process_task / wf_process_task_actor / wf_process_cc_instance,加上同一套状态机(实例 10/20/45、任务 10/20/99)和同一套提交行为(submitType 0~6 + 20)。六语言引擎读写的是同构数据------今天 Java 起的流程实例,Go 栈的引擎能直接读,因为表结构、状态码、字段约定都一样。
这对企业意味着:流程定义和历史数据是业务资产,不是某门语言的私有格式。技术栈要动的时候,工作流数据不用迁移。
2. 一套流程定义,六语言通用
15 个共享流程模板(审批/会签/条件分支/并行/驳回/抄送/一票否决......)只有一份,放在 jeeflow-java/jeeflow-core/src/test/resources/flows/,六语言 demo 直接读同一目录(Rust demo 就是 ../../jeeflow-java/.../flows 相对路径读进去的,PHP demo 同理)。流程 JSON 是 LogicFlow 格式,设计器画出来、哪个语言的后端都能跑。
3. 同一个库,换个语言接着用
一键部署的八栈共享同一个 MySQL 种子镜像(mldong-plus 库,45 张表:wf_process_* 8 + sys_* 23 + biz_* 11 + dev_* 3),同一个演示账号。想对比"同一个流程 Java 和 Go 跑起来有没有差别",起两个栈、连两个库,答案就是没有差别------这正是验收在验证的事。
一句话:六语言不是让你同时用六门语言,而是保证你不会因为选了某门语言,就被它锁死。
四、一条 curl 背后:deploy.sh 做了什么
deploy.sh 不长,逻辑对八栈一致(以 Rust 栈为例):
bash
# 1. 拉镜像(API 默认固定生产 tag)
docker compose -p "$PROJECT_NAME" pull
# 2. 启动四容器:backend + frontend(nginx) + mysql + redis
docker compose -p "$PROJECT_NAME" up -d
# 3. 等 MySQL healthy
# 4. 轮询真实登录,直到返回 "code":0
for i in $(seq 1 60); do
body=$(curl -s -m 3 -X POST "http://127.0.0.1:28100/sys/login" \
-H "Content-Type: application/json" \
-d '{"userName":"superAdmin","password":"123456"}' || true)
if echo "$body" | grep -q '"code":0'; then
echo "✅ API 就绪"; break
fi
sleep 3
done
两个值得知道的工程约定:
- 就绪判定是"登录成功",不是"端口通了" 。端口可连但应用没起来(冷启动、数据源没连上)会被继续等,直到真实登录返回
code:0才算部署完成。 - 八栈共享同一个前端镜像 ,nginx 里硬编码了
proxy_pass http://backend:8080/------所以所有栈的后端容器内必须监听 8080。Go 栈就栽在这:GoFrame 默认端口 18084,第一次接入时前端/api/全 502,登录页卡死;改成 8080 才通。这种"藏在别人配置里的契约"是多栈共用的最大暗坑,现在写在 compose 注释里了。
八栈端口各段错开,一台服务器同时起 8 套不冲突:
| 栈 | 前端 | API |
|---|---|---|
| boot4 | 21080 | 24000 |
| boot3 | 22180 | 25100 |
| boot2 | 22080 | 25000 |
| goframe | 20080 | 23000 |
| nestjs | 27080 | 27000 |
| fastapi | 23180 | 26100 |
| laravel | 18082 | 18083 |
| salvo | 28080 | 28100 |
(每栈还有各自的 MySQL/Redis 端口,compose 里有;清理用 docker compose -p <项目名> down -v。)
五、为什么说"发布过的字节 = 你拿到的字节"
deploy.sh 拉的后端镜像 tag 是 compose 里参数化的:${BACKEND_IMAGE:-生产tag}。
- 你(用户)拉的是固定生产 tag------这个 tag 对应的镜像,是先在"候选 tag"上把四层验收(L0 部署就绪 / L1 API 形状契约 / L2 API 语义冒烟 / L3 前端全流程 E2E)全部跑绿之后,才原样晋升(retag,不重建,镜像 ID 不变)的;
- 最近一轮(2026-08-24 七栈 + 08-25 Rust 栈):八栈 L0--L2 全部 19/19,L3 全部 14 过 / 1 固定 skip / 0 失败,单栈 6~8 分钟。
发布链路上周还堵过一个更隐蔽的坑:Rust 引擎 v1.0.0~1.0.4 五个 tag 的发布 CI 全部显示 success,但 crates.io 上四个 crate 全是 404------账号邮箱没验证,上传被拒,而脚本失败后没 exit 1,照样打印"✅ published"。假成功比失败危险 :失败会拦你,假成功会让"已发布"变成既定事实。修了两条:任一 crate 失败即标红退出;留一条 gh workflow run release.yml -f tag=<tag> 的重触发路径。
发布链路的铁律:"报告成功"必须等于"可验证地成功"------镜像要回拉验 ID,包要仓库实查。
结语
一条命令,几分钟后有一套能点的工作流应用;六语言任选,数据不绑死任何一门。
这就是本篇的全部。引擎内部怎么设计(状态机、流程定义、DDD、SPI、会签)前 8 篇已经拆过,这一季讲"引擎长什么样"之后的事------它怎么以可部署、可验证、可替换的形态交到用户手里。
下一篇进入联邦的方法论:[第 10 篇 · 跨语言对齐方法论:参考实现先行 + 契约测试](#第 10 篇 · 跨语言对齐方法论:参考实现先行 + 契约测试 "#") ------ 同一份契约在六语言里怎么对齐、怎么验证、升级为什么必须严格串行?
参考资料
- 一键部署区(八栈命令 + 端口说明)
- jeeflow GitHub(六语言引擎) · jeeflow-rust
- jeeflow 文档站
- 开源演示站(一前端多后端,nginx path 前缀切换语言)
- 集成演示站
- crates.io · jeeflow-core
下一篇预告 :[第 10 篇 · 跨语言对齐方法论:参考实现先行 + 契约测试](#第 10 篇 · 跨语言对齐方法论:参考实现先行 + 契约测试 "#") ------ 同一份契约在六语言里怎么对齐、怎么验证、升级怎么传播?