dev@workstation: ~/notes
$ whoami
程序员。写代码,也修自己挖的坑。
$ cat mission.txt
把每一次踩坑、每一次排障、每一次「原来如此」都记下来——
经验不沉淀,就会以同样的代价再付一遍。
$ ls ./lessons | wc -l
6 条教训,持续更新中▊

// Lessons Learned

运维

nginx 报 unknown directive "#":一个看不见的 BOM

Windows 下生成的 UTF-8 配置文件默认带 BOM(EF BB BF),传到 Linux 后 nginx 把它当成指令名解析,报错行号还会骗人。教训:配置文件走 SFTP 二进制传输,别复制粘贴进终端;给 Linux 的配置尽量用纯 ASCII。

运维

502 不一定是 nginx 的锅,先分层定位

看到 502 直接怀疑反代配置是本能,但更常见的是后端没起来。三板斧:看 error.log 是 Connection refused(后端没监听)还是 Permission denied(SELinux 拦截);本机 curl 127.0.0.1 验证后端;再回头查 nginx。日志永远比猜测可靠。

Python

虚拟环境不是可选项

图省事把包装进系统 Python,迟早互相冲突、牵一发动全身。每个项目一个 venv,依赖固化到 requirements.txt,部署机上一条 pip install -r 搞定。十分钟的前期投入,省掉几小时的依赖地狱。

数据库

SQLite 记得开 WAL 模式

多进程读写时默认日志模式会报 database is locked。建库第一句执行 PRAGMA journal_mode=WAL;,读写不再互斥;再配一个定时 .backup 备份任务,单机小服务足够稳。

习惯

「改了」和「生效了」是两回事

改完配置先 nginx -t 再 reload,改完代码 systemctl restart,改完防火墙 firewall-cmd --reload。所有「我明明改过了」的问题,最后复盘发现都是没生效。验证动作要成为肌肉记忆,而不是可选步骤。

安全

密钥不进代码库

Cookie、密码、AccessKey 一律放独立配置文件,权限设 600,加入 .gitignore。代码可以开源,密钥不行——泄漏一次,重置的成本远高于一开始多花的十分钟。