简历回答逐字稿:低代码执行状态实时同步
关联:简历追问:低代码执行状态实时同步、15分钟:低代码平台。
30 秒开场
这块我主要解决的是长耗时流程的可观测性。低代码工作流里会有 HTTP 调用、批处理、跨系统同步这类节点,如果用户只能看到一个 loading,很难知道流程卡在哪里、哪个节点失败、失败原因是什么。
所以我在 NestJS 侧做了 SSE/WebSocket 的执行状态推送。服务端把 execution started、node started、log、progress、node finished、node failed 这些事件流式推给前端,前端在画布和日志面板里实时展示。
如果面试官问:为什么用 SSE 或 WebSocket,不用轮询?
我会说如果只是偶尔查一次状态,轮询可以。但长任务调试场景里,日志和节点状态是持续变化的,轮询要么延迟明显,要么请求量大,而且很难表达增量日志。
SSE 适合服务端单向推送日志和进度,实现简单,浏览器原生支持断线重连。WebSocket 更适合双向交互,比如用户在执行过程中暂停、继续、发送调试命令。实际选型可以按场景拆,不一定所有地方都用 WebSocket。
如果面试官追:事件模型怎么设计?
我会说我会把事件设计成结构化而不是纯文本日志,比如:
{
"eventId": "...",
"executionId": "...",
"nodeId": "http_1",
"type": "node_log",
"level": "info",
"message": "request started",
"timestamp": "..."
}节点状态事件和日志事件可以走同一条通道,但类型要清楚。前端根据 eventId 去重,根据 timestamp 或 sequence 排序。这样刷新、重连、重复推送时不会把日志显示乱。
如果面试官追:断线恢复怎么做?
我会说不能只把事件存在内存里,否则用户刷新页面就丢了。
执行状态和关键日志需要持久化,至少最近一段日志或按 executionId 存储。SSE 可以利用 Last-Event-ID,客户端重连时带上最后收到的 eventId,服务端从这个位置继续补发。如果日志量很大,也可以只补状态快照,然后让用户分页查看历史日志。
如果断线期间流程已经结束,前端重连后应该先拿 execution summary,再接上日志尾部,而不是重新执行任务。
如果面试官追:日志量很大,前端怎么不被刷爆?
我会这样回答:
这里要做两层限流。
服务端侧可以按节点、level、频率做采样或合并,比如进度事件只保留最新值,debug 日志默认不全量推。客户端侧不能每条日志都 setState,可以用队列加 requestAnimationFrame 批量 append,或者虚拟列表展示日志。
如果是每秒上千条日志,UI 不应该试图实时渲染全部,而是展示摘要、计数和可下载明细。实时面板服务的是定位问题,不是替代日志系统。
如果面试官追:权限和多用户订阅呢?
我会说订阅执行流必须校验用户是否有权限查看这个 execution。多租户场景下,executionId 不能裸奔,服务端要校验租户、用户角色、流程所属空间。
多个用户看同一个执行实例时,不应该启动多份任务,而是订阅同一个事件源或广播通道。任务执行和日志订阅要解耦。
收尾句
所以这块的价值不是“用了实时通信”,而是把流程执行从黑盒变成可观察过程。用户能看到节点状态、变量错误、接口失败和重试过程,开发和实施排查成本会低很多。