用 stat 归并 failed_when 判空与 changed_when 抑制无效报告的写法
在写 Ansible playbook 时,最常见的一个"报告污染"场景是这样的:先用 stat 判断某个文件或目录是否存在,存在就删掉再创建,不存在就直接创建。逻辑本身没错,但跑完之后你会发现 PLAY RECAP 里那一台机器明明什么都没改,却显示 changed=1;或者更糟,stat 的结果注册成变量后,后续 when 判空没写对,直接抛出 'dic
FWDD.NET · 技术文档站
聚焦后端工程实践:语言教程、功能实现、面试题与运维脚本。每篇都从真实踩坑场景出发,给出可直接复用的代码与取舍依据。
在写 Ansible playbook 时,最常见的一个"报告污染"场景是这样的:先用 stat 判断某个文件或目录是否存在,存在就删掉再创建,不存在就直接创建。逻辑本身没错,但跑完之后你会发现 PLAY RECAP 里那一台机器明明什么都没改,却显示 changed=1;或者更糟,stat 的结果注册成变量后,后续 when 判空没写对,直接抛出 'dic
批量任务脚本最怕的不是失败,而是失败得不明不白。一个循环里跑了 200 个对象,第 37 个因为网络抖动挂了,第 88 个因为鉴权过期挂了,第 150 个因为目标已存在挂了——三种原因,三种处理方式:第一种该重试,第二种该中断整个批次去换凭证,第三种根本不该算失败。可现实中大多数脚本只写了一句 || exit 1,于是所有失败糊成一团,运维只能翻日志人肉还原
做 MySQL 面试复盘时,经常被候选人用一句话搪塞过去:Using index condition 就是索引下推,Using where 就是回表。这个回答在大多数场景下不算错,但只要面试官追问一句「那 Extra 里同时出现 Using index condition; Using where 该怎么解释」,八成的人就卡住了。本文从优化器实际行为出发,把
这道题几乎每次问「浏览器渲染流程」都会被带出来:给 <script> 加上 defer 或 async,DOMContentLoaded 到底在什么时候触发?很多人的回答停留在「defer 在 DOMContentLoaded 之前、async 不确定」,这个说法不算错,但被追问一句「多个 defer 脚本之间谁先执行」「async 脚本会不会插
线上做热点行计数,两套 SQL 都能实现「不存在就插入、存在就更新」:REPLACE INTO 和 INSERT ... ON DUPLICATE KEY UPDATE。业务语义看起来几乎一样,但在唯一索引冲突时,二者在 InnoDB 里走的路径完全不同:一个先删后插,一个先尝试插入再改走更新。路径不同,产生的锁就不同,锁不同,并发下的死锁概率和主从延迟就不
业务里经常遇到这样一张表:设备状态流水 device_status,每台设备每上报一次就插一条记录,同一台设备会有多条历史行。报表要的却是「每台设备最新那一条」——也就是按 device_id 分组、取 reported_at 最大(或 id 最大)的那一行,并且要把这一行的完整字段(状态、温度、电量、上报人)都取出来,而不是只取一个聚合值。 很多人第一反应
服务端代码里最常见的一句日志大概是 context canceled。它出现在 gRPC handler、HTTP middleware、后台任务、数据库调用的错误分支上,几乎没有任何信息量:是客户端主动断开,是超时兜底,是服务优雅退出,还是上游逻辑判定参数非法主动放弃?这四种情况的处置方式完全不同,但日志里长得一模一样。 Go 1.20 给 context
很多站点做移动端适配时,第一反应是改后端代码:在 Controller 里读 User-Agent,判断是不是手机,再决定跳 m. 域名还是返回不同模板。这种写法能用,但把「流量分发」这件本该由接入层处理的事塞进了业务代码,结果是每个语言、每个服务都要重复实现一遍判断逻辑,正则写得还不一致;更麻烦的是灰度阶段想临时改规则,得重新发版。 Nginx 的 map
很多人第一次碰到 TypeError: ' 或者 RuntimeError: dictionary changed size during iteration,都是在给 dict.keys() 做排序、切片、索引的时候。表面上看 d.keys() 像一个列表,实际它是 视图对象(view object),不持有数据副本,而是实时反映原字典的结构。这个特性在遍