设计可被脚本稳定调用的 CLI
命令行工具不仅面向人在终端中阅读,也经常成为自动化流程的一部分。输出格式和退出码因此属于公开接口。 区分输出通道 正常结果写入标准输出,诊断和进度写入标准错误。这样调用者可以安全地把结果传递给下一个命令。 提供机器格式 表格适合人阅读,JSON 更适合程序消费。字段名称应保持稳定,新增字段通常比修改现有语义更安全。 明确退出码 成功返回零,可预期的未找到、参数错误和远端失败应返回非零。不要用成功退出配合错误文本让脚本自行猜测。
命令行工具不仅面向人在终端中阅读,也经常成为自动化流程的一部分。输出格式和退出码因此属于公开接口。 区分输出通道 正常结果写入标准输出,诊断和进度写入标准错误。这样调用者可以安全地把结果传递给下一个命令。 提供机器格式 表格适合人阅读,JSON 更适合程序消费。字段名称应保持稳定,新增字段通常比修改现有语义更安全。 明确退出码 成功返回零,可预期的未找到、参数错误和远端失败应返回非零。不要用成功退出配合错误文本让脚本自行猜测。
主机数量增加后,手工输入地址、端口和密钥容易出错。~/.ssh/config 可以为每台主机建立稳定别名,同时保持命令简短。 按主机声明参数 显式配置 HostName、User、Port 和 IdentityFile。启用 IdentitiesOnly 可以避免客户端依次尝试过多密钥。 谨慎使用连接复用 ControlMaster 能减少重复握手时间,但共享连接会延长已有会话的生命周期。控制 socket 应存放在权限受限的目录。 保持主机密钥校验 不要全局关闭 StrictHostKeyChecking。服务器重装或地址复用时,应先从可信渠道核对新指纹再更新记录。
SQLite 数据库看起来只是一个文件,但应用运行时可能同时存在 WAL 和共享内存文件。直接复制主文件可能得到不一致的快照。 使用内置备份能力 优先使用 SQLite backup API 或命令行的 .backup。它们会在事务边界内读取一致数据,并允许应用继续提供服务。 检查输出 备份结束后执行 PRAGMA integrity_check,再查询关键表数量。备份文件应复制到与主机故障域不同的位置。 定期恢复 在临时目录打开备份并运行最小业务查询。只有恢复演练成功,才能证明权限、版本和加密参数都已记录完整。
评审质量会随着变更规模快速下降。把格式化、重构和业务修改混在一起,会掩盖真正需要判断的行为差异。 每次变更回答一个问题 提交说明应包含目标、行为变化和不在范围内的内容。需要迁移或兼容处理时,明确上线顺序和回滚条件。 给出验证证据 列出实际执行的测试、构建和手工检查。无法验证的环境项应标记为待办,而不是用本地结果代替生产结论。 优先检查边界 权限、错误处理、并发和数据兼容通常比代码风格风险更高。评审时间应先投入这些位置。
完整复制生产基础设施成本高,也不一定能复现真实流量。更实用的目标是保证关键接口、版本和失败语义一致。 固定依赖版本 数据库、缓存和运行时的大版本应与生产相符。团队已有共享开发服务时,应优先复用,避免每个项目重复启动一套状态组件。 用契约隔离外部系统 第三方支付、短信或对象存储可以使用测试环境或契约明确的替身。替身必须覆盖状态码、超时和字段约束,而不只是返回成功。 保留真实路径验证 发布前仍需在预生产环境验证网络、权限和迁移。单元测试通过不能证明基础设施集成已经完成。
项目中的构建、检查和生成命令很容易散落在文档里。Makefile 可以提供简短稳定的入口,并让持续集成复用相同命令。 目标名称表达意图 使用 build、test、lint 和 verify 等清晰目标。非文件目标声明为 .PHONY,避免同名文件导致任务被跳过。 输出实际命令 除非输出确实噪声很大,不要隐藏所有命令。失败时能够看到参数和工作目录,会显著缩短排查时间。 控制职责边界 Makefile 适合编排已有工具,不适合承载大量条件逻辑。复杂发布流程应放入可测试脚本,Makefile 只负责调用。
把 .env 加入忽略列表只能减少误提交,并没有解决密钥分发、权限和轮换。首先要知道每个秘密由谁生成、在哪里使用。 仓库只保存结构 示例配置可以列出变量名称和格式,但不放真实值。程序启动时应检查必需变量,并避免把秘密回显到错误日志。 限制读取范围 密钥文件只授予运行账户读取权限。容器挂载时使用只读模式,不要把整个宿主机配置目录暴露给单个服务。 设计轮换路径 轮换前确认服务是否支持新旧凭据并存。完成切换后撤销旧值,并检查日志中是否仍有旧客户端访问。
检查清单的目的不是增加审批,而是在压力下减少遗漏。内容应短、可观察,并与当前系统保持同步。 发布前 确认构建来源、配置差异、数据库兼容性和备份状态。涉及证书、DNS 或防火墙时,提前验证控制权限仍然有效。 发布中 记录开始时间和执行者,一次只改变一个阶段。每一步都要有继续条件,出现异常时停止扩大影响范围。 发布后 除了健康接口,还要检查真实用户路径、错误率和资源变化。回滚材料保留到观察窗口结束,再清理临时文件。
缓存可以降低延迟,也可能让修复后的内容长期不可见。策略需要根据资源是否可变、是否包含用户数据分别设计。 可变页面使用再验证 HTML 通常适合较短缓存或 no-cache,允许浏览器保存副本但每次使用前向服务器确认。ETag 可以减少未变化内容的传输。 指纹资源长期缓存 文件名包含内容哈希的 CSS、脚本和图片可以使用较长 max-age 与 immutable。内容改变时生成新 URL,而不是覆盖原文件。 私有数据禁止共享 带用户身份的响应应明确 private 或 no-store。配置 CDN 前检查 Vary 和授权头,避免不同用户共享缓存对象。
遇到故障后连续修改多个参数,可能暂时恢复服务,却无法确认真正原因。更稳定的方法是一次验证一个可以被推翻的假设。 先记录现象 写清时间、入口、错误文本和影响范围。把观察事实与解释分开,例如“TCP 超时”并不等于“防火墙阻断”。 设计最小实验 每个实验只改变一个变量,并提前写下预期结果。可以只读验证时,不要先重启或清空状态。 保存反例 假设被推翻同样有价值。记录失败实验可以防止团队在下一轮排查中重复走相同路径。