翟志军 Jack Zhai 👋

软件工程师,10 年+ 经验:5 年 Java 后端开发 + 5 年 DevOps / SRE 实践。

📖 《Jenkins 2.x 实践指南》作者(销量 5000+)。自 2015 年笔耕至今,已写下 120+ 篇文章。

✍️ 这里记录我对 DevOps、SRE、Cloud Native、持续交付、领域驱动设计(DDD) 以及 职场成长 的思考与实践。信奉 Everything as Code。

Using BLA to Counter REA's AI Reverse Engineering: An Electron Example

English | 简体中文 What AI reverse engineering changes REA gives AI agents reverse engineering tools to inspect applications without source code and help reconstruct features. Can software companies still protect their implementations? How BLA responds BLA adds material that interferes with analysis to release artifacts. Decoy modules and call relationships give agents more leads to check. Expanded metadata can also reach a particular parser’s resource limits. The ASAR approach used here transforms JavaScript and expands archive directory information. Its goal is to keep the application usable while increasing analysis overhead or limiting particular entry points. Effectiveness depends on the artifact format and tool versions, so it needs evaluation. ...

2026-11-07 · 7 min · 1320 words · 翟志军 Jack Zhai

使用 BLA 进行反 REA AI 逆向——以 Electron 应用为例

English | 简体中文 AI 逆向带来的变化 REA 让 AI agent 借助逆向工具分析没有源码的应用,并辅助重建功能。软件公司还能保护自己的实现吗? BLA 如何应对 AI 逆向 魔高一尺,道高一丈。BLA 会向发布制品加入干扰分析的内容。诱饵模块和调用关系让 agent 面对更多待核对的线索,扩大的元数据则可能触及解析器的资源上限。 本例使用的 ASAR 方案会改写 JavaScript,并扩充归档目录。目标是保持应用可用,同时增加自动分析的开销或让特定入口受限。真实效果取决于目标格式与工具版本,需要后续评估。 以 Electron 为例接入 CI 示例仓库是 zacker330/bla-ci,包含简单的报价计算器和三平台 CI。在构建 job 生成原始 app.asar 之后加入 BLA,处理完成后再打包、生成完整性记录和签名。 加固会改写交付文件,后续打包若重新生成文件,就可能覆盖加固结果。把 BLA 接进构建,可以固定处理顺序,让每次发布都执行,并在失败时阻止交付。 原始制品 → 对照包 → 回归测试 └→ BLA → 加固制品 → 打包与回归 → 按渠道签名、封装及发布验证 两份制品 → 按时机评估反 REA AI 逆向效果 构建脚本保留原始 ASAR,再生成加固版本: npx --no-install bla audit dist/asar/original/app.asar --json npx --no-install bla protect dist/asar/original/app.asar \ -o dist/asar/hardened/app.asar --intensity bankrupt \ --seed bla-ci-demo-v1 --json npx --no-install bla verify dist/asar/hardened/app.asar \ dist/asar/original/app.asar --json 锁定工具版本和依赖,每次从原始制品重新加固。固定 seed 用于复现,不承担保密功能。命令或校验失败就停止构建,并保存报告。dist/build.json 记录版本、配置、产物哈希和耗时,让后续测试与评估能核对输入。 ...

2026-11-07 · 2 min · 279 words · 翟志军 Jack Zhai

[译] Skylark 设计一瞥

原文:A glimpse of the design of Skylark 作者:Laurent Le Brun。原文发布日期:2017 年 3 月 21 日。 译注:本文保留原文的 Skylark 名称和 2017 年的技术语境,文中的“当前”等时间表述均以原文发表时为准。原文来自 Bazel 官方博客,其源码仓库采用 Apache License 2.0。本文为中文翻译。 本文介绍 Skylark 的设计。Skylark 是 Bazel 中用于描述构建的语言。 简史 很多年前,Google 使用 Makefile 构建代码。正如其他人也曾指出的那样,Makefile 很难应对大型代码库。一个临时方案是用 Python 脚本生成 Makefile:构建描述保存在 BUILD 文件中,以调用 Python 函数的形式表达。但这个方案实在太慢了,瓶颈就在 Make。 Blaze 项目于 2006 年启动,后来以 Bazel 的名字开源。它用一个简单的解析器读取 BUILD 文件,只支持函数调用、列表推导式和变量赋值。当 Blaze 无法直接解析某个 BUILD 文件时,就会先执行一个预处理步骤:用 Python 解释器运行用户编写的 BUILD 文件,生成一个简化版的 BUILD 文件,再交给 Blaze 使用。 这种方法很简单,也允许开发者创建自己的宏。但它又带来了许多维护、性能和安全方面的问题。由于 Blaze 本身无法解析这些 BUILD 文件,各类工具的开发也变得更加复杂。 在当前版本的 Bazel 中,我们移除了 Python 预处理步骤,让系统变得更加合理。不过,为了迁移现有代码库,我们保留了 Python 语法。无论如何,这似乎都是个好主意:许多人喜欢 BUILD 文件的语法,其他构建工具,例如 Buck、Pants 和 Please,也采用了这种语法。 ...

2026-11-05 · 1 min · 134 words · 翟志军 Jack Zhai

我有一个 AI 同事

我很少在博客里写小说。但前段时间,我注意到一个现象:IM 上的技术讨论越来越有条理,越来越专业,也越来越不像人话。 于是,有了下面这个故事。故事纯属虚构。如有雷同,纯属正常。 晚上十一点四十七分,Slack 响了一声。 陈默正在盯着一块已经红了两个小时的 Grafana 面板。线上 API 的 P99 延迟从 180ms 爬到了 2.7 秒,重启 Pod 没用,扩容没用,数据库连接池看起来也正常。 消息来自他的同事老周。 我分析了一下,目前最可能有三个原因: 数据库慢查询导致连接池排队; Redis 出现热点 Key; 下游支付服务响应时间异常。 建议按照以下顺序排查…… 陈默看了两眼。 很有道理。 但他懒得想。 他切到另一个窗口,把老周的消息复制进去。 “这是我同事对线上故障的分析。你觉得他说得对吗?还有没有遗漏?” 几秒后,屏幕上开始吐字。 你同事的分析总体是合理的,但还可以进一步考虑以下几个方向…… 陈默快速扫了一遍,删掉最后一句“如果你愿意,我可以帮你整理一份完整的排查 checklist”,然后复制到 Slack。 我觉得除了这三个方向,还应该检查: Node CPU throttling; CoreDNS 延迟; Service Mesh sidecar 是否出现连接堆积; 最近是否有配置变更。 我建议先从最近变更入手,因为问题发生得比较突然。 不到一分钟,老周回复: 同意。从时间点来看,配置变更确实值得优先排查。另外我补充一点:如果是 Istio sidecar 导致的问题,可以对比应用容器和 Envoy 的 upstream request time…… 陈默盯着这段话。 不知道为什么,他觉得老周今天说话特别有条理。 他顺手复制。 “我同事这么回复。下一步我应该怎么回答?” AI 说: 可以这样回复: “同意。我们先查最近一小时的 deployment 和 config change。我来检查 Kubernetes event 和 ArgoCD,你帮忙看 Istio metrics,这样可以并行推进。” ...

2026-08-27 · 3 min · 500 words · 翟志军 Jack Zhai

不知道运维在忙什么

前段时间,我从领导那里得知,有其他团队的人说:“不知道运维在忙什么”。我懒得打听是谁说的,所以就暂时把这个“谁”称为:说话人。 而我作为运维的 leader,很早前就预料到有人会说这句话。在我自己看来,就两种情况:有人想搞运维团队(坏),或者那个人太不懂职场(菜)。 为了避免我个人情绪,我问了一下 AI:“有人向领导说这话”是什么含义,得到的答案是: “不知道运维在忙什么”通常不是中性询问,而是在领导面前暗示: - 运维工作不透明; - 运维没有及时响应; - 运维可能没做出成果,甚至“瞎忙”。 这是一种比较隐晦的负面评价。尤其当对方没有先向运维了解情况、也没有指出具体事项,却直接在领导面前说,确实带有甩锅、质疑或贬低的意味。 不论是哪种答案,本质上并不是我预料有人会说这句话,而是预料到信息不透明、话语权不对等的情况,发生这样的事情,我觉得是必然的。 我在世界500强、初创公司、上市公司、跨国公司待过,我见过一些世面了。 因此,我管理团队时,选择通过看板管理来公开团队的所有工作,一方面管理自己的团队,一方面预防在出现“情况”时,好有数据来自证。我统计了引入 AI 工具后,最近半年我们完成的工作量提高了 40% 多。 既然,运维团队公开了所有的工作,为什么还有人说不知道运维在忙什么?有几种可能: 说话人没有看,或者没有心思主动去看我们的工作。 运维团队没有同步到位。 情况1,没有什么好说的,大家都是成年人。 关于情况2。运维团队每天都会在看板前进行站会。 当其他团队来找运维团队提需求后,运维团队要多久向其他团队的人同步呢?要运维团队每打一个字就同步吗?当然不是,而是根据不同的团队的“同步频率需求”,来同步。 但是,反过来想,站在公司整体经营成本的角度来想,与其让运维团队花成本来解决“同步”的问题,不如其他团队主动问一句运维团队,这样是不是成本更低?我懒得深究这个情况了。 最终,我开发了一个 bot。v1 版本有2个功能: 只要有人在公司群里发:@infra 在忙什么,bot 就会把运维团队看板上所有 doing 的任务都列出来。 @infra subscribe <ticket> 就可以订阅任何一张卡的状态变更通知。我们运维也不用思考要多久同步,你关心就自己订阅。 这个 bot 只是为了堵住说话人的口,也是职场上的一种正面的回应。 本来,本文就应该停止了。好奇心让我深入思考了这类事件的背后。本质就是话语权不对等的结果,是不同成员影响决策、定义问题和表达异议的能力不平等。 假设软件工程会经过以下流程: 产品经理 -> 设计 -> 开发 -> 运维 -> 测试 这个流程中,谁有向上说话的权力,谁就有权力判定下游工作。假如开发有向上级说话的权力,当开发说:目前卡在运维。 那么,说一次还好,每次开发都这么说。信息传到上级的意思就是:运维工作不行。把“运维”换成“测试”,结果是一样的。 但是,我知道的是,当上级预期是10天完成上线时,而开发占用了9天,留给运维和测试的时间只有1天,也就是最后一天才通知运维要进行上线工作。那么,我们会如何看待开发,以及开发说的“目前卡在运维”呢? 这里只是以开发角色举例,换成其它角色,同样的问题。 那么,我们应该如何解决“话语权不对等”所带来的问题呢?是让话语权平等吗?我也不知道答案。我会继续研究下去。 最后,希望世界和平。

2026-08-22 · 1 min · 59 words · 翟志军 Jack Zhai

什么是手工运维

一个夏天的午后,知了嘈杂,窗下的我 review AI 写好 IaC 代码后,敲下部署到线上环境的命令。 看着终端的日志滚动,一个问题突然蹦入我的大脑:什么是手工运维? 像我这样使用 IaC 来管理基础设施: 过去是手打代码,这算吗? 现在是 AI 写的代码了,但是 prompt 依然是手打,这算吗? 代码是 AI 写了,但是执行,还是需要手工的,这算吗? 如果不使用 IaC,改成使用 GUI,人们可以在界面上点一下“部署”按钮,就完成了整个服务的部署,这算不算手工运维呢? 像 Cloudflare 或者 Vercel 上,开发者都不用点,只需要将写好的业务代码 push 到远程的 git 仓库就可以了,部署和自动化的域名都给自动化完成了,这算不算手工运维呢? 先说结论:不论是使用 GUI 还是 IaC,如果无法做到自动编排部署任务,都是手工运维。 过去,运维人员通过 SSH 一条条命令的输入到服务器,大家都认为那是手工运维。但是,如果把这些命令写成 bash 脚本,可以一键执行,这算自动化运维了吗? 现在,人们在 GUI 界面上,一个个按钮的点击界面,最后点击“部署”按钮,我认为这与通过 SSH 一条条命令运维没有什么区别,也是手工运维。只不过 GUI 的动作的粒度比 SSH 命令大一些。 本质上,以上两种方式,都需要人工编排部署任务,也就属于手工运维。 而 Cloudflare 或者 Vercel。单服务时,不需要编排部署,所以人们觉得自动化运维。但是如果是多个服务,Cloudflare 或者 Vercel无法做到自动化编排部署任务,它依然是手工运维。 所以,使用 IaC 来管理基础设施,算手工运维吗?取决于你的 IaC 代码:当人表达意图后,它能否自动输出部署计划,并且能自动化运行。 如何做到?这是另一个话题了。 希望这篇文章给你带来启发。多谢。

2026-07-10 · 1 min · 63 words · 翟志军 Jack Zhai

Precise Testing Is Wrong — It's Just a Byproduct of Incremental Builds

There’s a popular idea in the testing world called precise testing (精准测试). In short, it is the ability to run only the tests affected by a change, instead of running the entire suite every time. I think the idea is right — but the way our industry usually implements it is wrong. In this post I’ll first explain what precise testing is and why the mainstream approach is heading in the wrong direction, and then show a different path: precise testing turns out to be nothing more than a byproduct of incremental builds. ...

2026-06-29 · 9 min · 1818 words · 翟志军 Jack Zhai

The Hidden Trap in Technical Decisions: Trading a One-Time Cost for Continuous Debt

Our team uses more and more AI services—OpenAI, Deepseek, Tongyi, Doubao, Claude… Each platform has its own API, its own keys, its own billing model. The configuration gets messier, the calls get more scattered, and so sooner or later someone proposes: Why don’t we build our own AI Gateway? Either build it ourselves, or buy one off the shelf. It’s a very natural idea. I’ve had it too. Build an AI Gateway and solve all the problems at once—what a great KPI story. ...

2026-06-14 · 8 min · 1651 words · 翟志军 Jack Zhai

技术决策的隐藏陷阱:用持续负债消除一次性成本

团队里用的 AI 服务越来越多——OpenAI、Deepseek、通义、豆包、Claude……每个平台一套 API、一套 Key、一套计费口径。配置越来越乱,调用越来越散,于是总有人会提出: 要不我们自己搭一个 AI Gateway 吧?自建,或者买个现成的。 这个想法非常自然。我也有过。 搭建一个 AI Gateway 一次解决所有的问题,多好的 KPI 叙事。 但是,仔细一想,把账一算,我决定放弃在公司里自建 AI Gateway。 先给结论 对绝大多数公司来说,自建或购买 AI Gateway 的 ROI 都很低。 注意,决定性的因素不是你用了多少种 AI 服务。哪怕你接了十几个平台,只要项目规模没到、团队能力没到,这笔投入依然不划算。 真正划算的前提只有一个组合:项目数足够多,且你本来就有一支扛得住 7×24 的运维/平台团队。 否则,你大概率是在用一个永久性的负债,去换一两天就能消化掉的麻烦。 下面展开说为什么。 一、AI Gateway 到底解决了什么 先得承认,AI Gateway 的确能解决公司的一些问题: 多平台 fallback:同一个模型要在多个供应商之间兜底。比如 Deepseek,要做 Deepseek 官方 → 火山引擎 → 阿里云百炼 的 fallback 路径,每个业务都得自己写一遍。 API Key 轮换要重启服务:换一次 Key 就得重启应用。三个服务用到了就至少轮换三次,再乘上多环境(dev / staging / prod),数字很快就上去了。 请求监控各自为政:对 AI 调用的监控,每个业务都得自己实现一套。 接口不统一:想换模型,就得重新对接一个平台的 SDK,而不是一套接口打天下。 申请 Key 流程慢:业务向运维申请 Key,走流程要时间。 成本统计粒度粗:很多 AI 平台的成本统计很弱,做不到按 Key 或按 Project 维度归集,只能在业务代码里自己埋点。 这听起来非常的美好,也很能打动老板们。 ...

2026-06-14 · 2 min · 225 words · 翟志军 Jack Zhai

从法庭到代码:谁主张谁举证的工程实践

2023年,与开发商打了不少官司。学习了不少庭审知识。发现有些实践或者原则放到软件工程中也是有效的。就比如谁主张谁举证这一基本原则。 谁主张谁举证就是当事人对自己提出的主张提供证据并加以证明。 举例来说,张三说隔壁老王侵占了自己的宅基地。张三必须自己拿证据来证明自己说的事实。而不是让老王拿证据出来证明自己没有侵占。 在软件工程中,服务A调用服务B,出问题了。服务A认为是服务B的问题,这时,根据谁主张谁举证原则,服务A的开发应该自己找出证据来证明自己的观点是正确的,而不应该让服务B来提供证据证明自己没有问题。 因为如果让服务B证明自己没有问题,怎么证明自己没有问题呢?怎么证明,证据都不够充分。而且会浪费服务B的团队人力。 所以,在团队中,让大家达成“谁主张谁举证”的共识会带来以下好处: 节约团队的人力。如果服务A能提供有效证据,那么就不需要服务B去证明自己没有问题了。 倒逼团队形成故障现场保留的习惯,比如打印良好的日志等 不过,我们需要注意的是,“谁主张谁举证”并不意味着,服务B团队不配合服务A一起排查问题。在一个公司里,基本的团队协作原则与底线是要有的。 那是不是所有的场景都是谁主张谁举证? 也有特殊情况。有些场景,是需要进行举证责任倒置的。开发商要拿证据来证明自己的转供电是合法的,而不应该让业主拿证据来证明开发商转供电不合法。 也就是证据只能是“被告方”能提供的情况下,我们就不是谁主张谁举证了。 以上只是我个人的思维实验。 在工作中,作为DevOps工程师,我经常遇到开发者质疑云厂商的Redis或者RDS出了问题。 根据我过往的经验,只是质疑,没有证据的情况,大多是开发者自己代码的问题。通常我会自己看看监控的同时,会要求他们加日志,然后想办法复现问题。 最后,一个公司一个团队里,如何低成本的达成谁主张谁举证这个共识? 我目前还没有答案。

2025-09-13 · 1 min · 17 words · 翟志军 Jack Zhai