一句话说明
工业软件与智能制造:从客户现场的业务问题,做到能落地的产品与系统。
案例 1 · Minitab COM 桥接服务
核心约束:Minitab 只开放 C# 的 COM 组件接口,而 COM 组件无法被 Web 程序直接调用。
这一个约束决定了后面所有的事情 —— 它把选择空间砍到只剩两条路,
逼着每个取舍都必须有理由。
本站有一篇长文专门拆这个案例的决策链,那是我目前最想让你先读的东西:
FDE 的第一性问题:在写代码之前划定边界。
技术事实
以下事实来自我 2020 年的原始技术笔记(原文已归档进本仓库 git 历史):
- 写了一个 Windows 服务,开机自启
- 服务持续轮询一个 HTTP 接口取任务;接口参数含分析类型、子组大小、判异原则
- 服务收到参数后调用 Minitab COM 组件做统计分析,生成图表与文字说明
- 前端调用 Web 接口时必须传**唯一标识
OrderID**(实际是向数据库写一条记录),
之后前端循环查询该OrderID的结果
决策链
场景 —— 工业质量分析。让质量工程师在浏览器里看到 SPC 控制图,而不是每个
人在自己电脑上打开 Minitab 手动跑一遍。
模糊点 —— 初始需求只说了「想在系统里看到分析结果」,没有说清:
刷新频率、并发用户数、Minitab 授权是单机的、数据从哪里来、分析口径由谁定义。
边界
| 内容 | |
|---|---|
| In scope | 把 Minitab 的分析能力搬到浏览器里,让现场不必在每台机器上装软件 |
| Out of scope | 不做实时流式(改轮询);不替使用者决定统计口径;不重写分析算法 |
划出去的部分,恰恰是这套系统能被接受的原因。详见长文第四节的展开。
关键决策(≥2 个备选 + 代价)
| 决策 | 备选 | 代价 | 选了哪个 / 为什么 |
|---|---|---|---|
| 分析引擎 | A 用 C# 重写分析逻辑 | 必须重新验证统计正确性;客户历史报告与新系统对不上 | 选 B:不去替换客户已经信任的东西,而是让它进入新的工作流 |
| B COM 桥接 | 绑定 Windows + Minitab 单机授权;多一个进程边界要维护 | ||
| 调用方式 | A 同步等待 | 并发被 Minitab 实例数硬锁死;超时成为吞吐天花板 | 选 B:把代价从「不可控」挪到「可枚举」 |
B 异步 OrderID 轮询 |
多一次状态查询;要处理结果过期;前端多一个轮询循环 |
交付节奏 —— 原笔记未记录分期节点(此处不补写)。
结果(对比基线) —— L1 展示 无法量化。
原始笔记里只有技术描述,没有「原来 ___ 分钟/次 → 现在 ___ 秒/次」这类对比
基线。我不会为了让这一栏好看而补一个数字上去 —— 编造一个听起来合理的量化
结果,比承认无法量化严重得多。
运营与交接 —— ⚠️ 这是这个案例最诚实的部分:当年做得不完整。
原笔记里关于可靠性只有一句「开机后自动运行」,没有失败重试、日志、告警,
也没有 Minitab 进程崩溃或被占用之后的恢复方案。
「开机自启」不等于生产就绪,它只是「能被启动」。这是一个长驻的、单点的、
独占一个桌面软件授权的后台进程 —— 它挂掉之后前端会一直轮询、一直查不到结果,
而没有人会收到通知。
复盘 —— 如果要重做,我会在交付前先回答完四个问题:它怎么失败?失败之后
怎么被知道?失败之后怎么恢复?交接给谁?这四个问题没有一个和算法有关,但
它们决定了这是「一个能跑的 demo」还是「一个能交给别人用的东西」。完整的展开
见长文第五节。
可复现证据
L1 展示目标 L2把本案例抬到 L2(可复现) 需要四件套齐备 —— 脱敏数据样本、可执行的命令、
明确的版本、预期输出。当前状态:
| 要素 | 状态 |
|---|---|
| 环境与版本 | 待补齐 |
| 脱敏数据样本 | 待补齐 |
| 调用命令 | 待补齐 |
| 预期输出 | 待补齐 |
| 源码 | 客户合同限制,暂不开放 |
在四件套齐备之前,这一栏会一直标 L1。把等级标得保守一些是刻意的 ——
一个标成 L1 且每句话都能被追问的案例,比一个标成 L2 但经不起追问的案例
更有说服力。
案例 2 · Minitab 二次开发实时生成控制图
有一个可演示的交付物 —— 这在个人站上很稀缺,是本案例最大的资产。
实时生成 SPC 控制图的运行截图(2021 年交付时录制)
决策链
场景 —— 案例 1 解决的是「能不能在浏览器里看到分析结果」;本案例要解决的
是实时性 —— 让控制图跟着数据走,而不是等一次人工触发的分析。
模糊点 —— 原笔记未记录(不补写)。
边界 —— 原笔记未记录(不补写)。
关键决策 —— 原笔记只记录了结果,未记录取舍过程。此处不编造。
交付节奏 / 结果 / 运营与交接 / 复盘 —— 同上,原笔记未记录。
为什么这一栏是空的,而我不打算把它填满:
这两个案例是我自己的真实经历,但原始笔记记的是「做成了什么」,
不是「当时在几个方案里怎么选的」。后者需要我自己回忆、并与当时的
同事核实之后才敢写。在核实之前留空,比编一段读起来很顺的决策链诚实。
案例 3 · SPC 数据架构:不搬数据,搬能力
这是我在工业质量分析产品线上推动的一次架构级取舍。它值钱的地方不在于
最终架构长什么样,而在于我们放弃了哪条更省事的路。
场景 —— 制造业客户的质量数据散落在各自的业务库里:SQL Server、MySQL、
Oracle、PostgreSQL、MES、ERP,还有现场侧的 SCADA、PLC、CMM、传感器。
要在这之上做在线的 SPC 分析,第一件要决定的事就是:数据怎么进来。
模糊点 —— 「把数据接进来做分析」这句话,可以指至少两种完全不同的架构,
而它们的成本和后果差一个量级:
- 一种是把数据搬进来(ETL 复制到平台自己的库,再分析)
- 一种是让分析能力走过去(数据留在客户库里,平台去读、去算)
需求方说「要能分析」,但没有说这背后是哪种。这个模糊点不解决,后面所有
设计都是猜。
边界
| 内容 | |
|---|---|
| In scope | 一个统一的数据访问层 + 标准化测量事件模型 + 多分析引擎共享 |
| Out of scope | 不做「把客户全部历史数据复制进平台」。这条是主动划掉的,见下面的决策 |
关键决策(≥2 个备选 + 代价)
| 决策 | 备选 | 代价 | 选择与理由 |
|---|---|---|---|
| 数据怎么进来 | A 传统 ETL:客户库 → ETL → 复制数据 → 平台库 → 分析 | 客户库里已有大量累积的检测数据,全量复制意味着:存储翻倍、同步时效差、每一次历史追溯都要等一次搬运 | 放弃 |
| B 数据访问层:原始数据 → Data Access Layer → 标准化 → 分析引擎 | 要面对异构数据源(6 种数据库 + 4 类工业协议)、客户库的查询压力、内网与权限限制 | 采用 | |
| 分析引擎怎么取数 | A 每个引擎各自取数 | 写起来快。但 Minitab 一套、Python 一套,N 个引擎就是 N 套取数逻辑 —— 口径迟早漂移,而质量分析里「口径漂移」等于「两个系统算出的 CPK 不一样」 | 放弃 |
| B 统一测量事件:一次采集、一次标准化,多引擎共享 | 前期的建模成本明显更高,且要说服各引擎的维护方改接口 | 采用 |
选 B 的核心理由,用当时的话说是:
能直接用,就不搬;需要持续分析,就增量;需要实时,就走数据流;
一次采集、一次标准化、多分析引擎共享。
这条原则的实质是把「复制」从一个默认动作,降级成一个需要论证的动作。
默认复制是很自然的 —— ETL 是成熟方案,工期可估,出了问题也好排查。
但它有一个隐形成本:它假设数据的所有权和使用权可以分离。
在工业现场这个假设经常不成立:数据可能几个亿、客户库里还在持续写入、
网络不通外网、甚至有合规要求不允许出库。
交付节奏 / 结果(对比基线) —— 我在这里不写数字:原始素材里描述了
架构演进的方向和原则,但没有留下量化的对比基线(如「查询耗时从 X 降到 Y」)。
按本站的证据纪律,没有依据的数字一律不补。
复盘 —— 这次取舍最大的收获不是技术上的,而是「不做全量复制」本身
就是一条 out-of-scope 判断。它需要在项目早期就被明确说出来,否则默认
路径一定是 ETL —— 不是因为 ETL 对,而是因为它最不需要解释。
可复现证据
L1 展示目标 L2架构演进的方向与原则是可核实的(见上)。但要抬到 L2,缺的是可跑的
最小复现:一个脱敏样本库 + 数据访问层的调用方式 + 统一测量事件的 schema
- 预期输出。这部分我暂不发布 —— 涉及客户数据结构。
案例 4 · 工业现场的五个真实难题
这一节和前面几个案例不同:它不是一条完整的决策链,而是五个反复出现的
现场难题,以及我们各自选择的对策。
我把它们放在这里,是因为工业软件的难点几乎全在这五件事上 ——
不是「系统怎么设计」,而是「系统怎么在客户那个环境里活下来」。
1. 大规模历史数据:不搬,直接查
问题 —— 客户数据库里已经积累了大量检测数据。全量复制到平台是不可行
的:存储翻倍、同步时效差、而且客户往往不允许数据出库。
对策 —— 直接查询 + 增量分析 + 数据访问层。
这条和 案例 3 · SPC 数据架构 是同一个判断的不同侧面:
把「复制」从一个默认动作,降级成一个需要论证的动作。
2. 多数据源:统一模型,而不是统一接口
问题 —— 不同客户的技术栈完全不同:SQL Server / MySQL / Oracle / MES / SCADA / Excel / MQTT / TCP。
如果为每一个数据源写一条独立的分析链路,维护成本会随客户数线性增长。
对策 —— 通过统一数据模型进行标准化。数据源适配层只负责「把它翻译成
标准形状」,分析侧完全不知道数据来自哪里。
3. 实时生产数据:Edge 到报警的完整链路
问题 —— 现场设备持续产生检测数据,需要实时看到控制图与异常报警,
而不是等一次人工触发的分析。
对策 —— Edge → 数据流 → 标准化 → SPC Engine → 实时控制图 → 报警。
这条链路也解释了案例 1 · Minitab COM 桥接服务为什么要用轮询 ——
「实时」在工业现场的约束下,不等于「低延迟」,而等于
「在客户现有的授权和部署条件下能持续跑」。
4. 多算法引擎:Python 和 Minitab 共存
问题 —— 系统里同时存在 Python 和 Minitab 两套算法。
它们是不同的技术栈、不同的调用方式、不同的部署要求。
如果各自取数,两边算出的结果迟早会对不上 —— 而在质量分析里,
「同一份数据算出两个不同的 CPK」是灾难。
对策 —— 统一分析接口,让不同分析引擎共享标准化测量数据。
引擎各写各的,但数据形状只有一个。
5. 复杂部署环境:真实的客户现场长什么样
问题 —— 客户现场的环境约束远比「装个 Docker」复杂:
- Windows / Linux 混合环境
- 企业内网、部分场景无互联网
- 数据库隔离,不能直连
- 网络权限受限
对策 —— 把部署方案当作产品的一部分来设计,而不是实施阶段的临时问题。
这一条是我认为工业软件和互联网软件最大的一道分界线。
互联网软件可以要求用户升级浏览器;工业软件不能要求客户改网络架构。
这一节为什么没有证据等级徽章?
上面五条是对策的方向,不是「已量化验证的结果」 —— 原始材料里没有留下
任何一个数字(没有「查询耗时从 X 降到 Y」,也没有「支持了 N 个客户」)。
按本站的证据纪律,我不补数字,也不给它们挂一个暗示「已被验证」的等级。
这五条现在的价值在于:它们展示了我在工业现场会优先关注什么。
等你补齐可核实的案例细节,我们再逐条升级成完整案例。
案例 5 · 这个站本身
这是一个正在发生的案例 —— 我知道它现在处于什么状态,
而且它每天在被使用。
场景 —— 我需要一个能承载 FDE 求职的材料载体:不是博客,是作品集。
访客需要在 20 秒内看到「交付过什么」,而不是「写了多少篇笔记」。
模糊点 —— 一个 Hexo 博客离「求职门户」差多远?最开始我不知道。
把它拆开之后发现,差的不是设计,是信息架构和证据纪律。
边界
| 内容 | |
|---|---|
| In scope | 信息架构重排(作品前置)、案例按决策链写、证据分级、CI 自动构建 |
| Out of scope | 不做通用博客主题、不保留旧笔记的全部 URL、不为好看而动效 |
关键决策
| 决策 | 备选 | 代价 | 选择 |
|---|---|---|---|
| 配色 | A 亮天蓝 #49b1f5(2016 博客审美) |
与企业级 / ToB 语境脱节 | 选 B |
B 深靛蓝 #1f4e79 |
更克制、不抓眼球 | ||
| 正文容器 | A 只覆盖 .post-content(文章页) |
/resume/ /works/ 仍是博客默认样式 |
两者都覆盖 |
B 只覆盖 .custompage(独立页) |
文章页排版割裂 | ||
| 证据表达 | A 满屏彩色徽章 | 访客只看到颜色,看不到等级文字 | 选 B |
| B 中性灰徽章 + 彩色圆点 | 需要读者多看一眼 |
结果 —— 站点从「60+ 篇笔记的博客」变成「4 个页面的作品集」,其中/works/ 和 /resume/ 承担全部说服力。旧的 61 篇技术笔记已从站点下线
并归档进 git 历史 —— 它们仍在版本控制里可查,但不再占据访客的注意力。
运营与交接 —— CI(GitHub Actions)负责构建与部署;npm run check
负责校验履历字段是否齐全。维护清单在 tools/LEFTOVER.md。
复盘 —— 最大的收获是「不做什么」比「做什么」更需要判断力。决定下架
61 篇笔记的犹豫程度,不亚于当初写它们所花的总时间。
可复现证据
这套站点的证据是完整可复现的 —— 因为它就在你眼前:
| 要素 | 内容 |
|---|---|
| 版本 | Hexo 5.4.2 · hexo-theme-stun(主题已纳入版本控制) |
| 运行 | npm install && npm run server → http://localhost:4000 |
| 构建 | npm run build |
| 自检 | npm run check(扫残留待填项) |
| 数据源 | source/_data/profile.yml —— 全站身份信息的唯一来源 |
| 源码 | github.com/adymilk/blog_backup |
| 预期输出 | /works/ /resume/ /about/ 三页,构建 0 error |
这是全站第一个我可以诚实地标到 L2 的案例 —— 因为它的全部材料都在公开
仓库里,你可以自己跑一遍来验证我说的话。
关于证据的说明
本站所有案例都标注证据等级(L0–L3):
| 等级 | 含义 | 判定标准 |
|---|---|---|
| L0 | 声称 | “系统很稳定”,无测量方法。不算证据,本站不写。 |
| L1 | 展示 | 有截图 / 架构图 / 可演示的交付物 |
| L2 | 可复现 | 有数据、命令、版本、预期输出,别人能重跑 |
| L3 | 经使用验证 | 有真实使用者、对比基线、结果与限制 |
我倾向于把等级标得保守一些。
一个标成 L1 但每句话都能被追问的案例,比一个标成 L2 但经不起追问的案例
更有说服力。你可以按上面「可复现证据」一栏列的要素,逐条验证我说的话 ——
如果有哪一条对不上,欢迎直接告诉我。
如果你只想看一件事,看这个:我在这页上没有写任何我无法核实的数字。