滚动更新需确保老连接自然结束而非简单停服:nginx reload 逐步关闭worker,自建服务监听SIGUSR2/SIGHUP优雅启停;数据库迁移用pt-online-schema-change或CONCURRENTLY避免锁表;部署脚本须显式处理超时与信号;K8s需配置progressDeadlineSeconds和maxUnavailable保障可用性。
滚动更新时如何保证 HTTP 服务不丢请求
直接替换进程或重启 nginx / gunicorn 很容易触发 TCP 连接重置,客户端收到 ECONNRESET 或超时。关键不是“停不停”,而是“老连接是否被允许自然结束”。
- 用
systemd的Restart=on-failure配合StartLimitIntervalSec,避免崩溃后疯狂拉起新实例干扰旧连接 -
nginx更新配置后执行nginx -s reload,它会 fork 新 worker、逐步关闭旧 worker(默认等待worker_shutdown_timeout,建议设为30s) - 对 Go/Python 等自建 HTTP server,需监听
SIGUSR2或SIGHUP,在新进程 bind 成功后再 graceful shutdown 旧进程;别依赖简单kill -9
数据库迁移怎么绕过锁表和主从延迟
DDL 操作(如 ALTER TABLE)在 MySQL 5.7+ 默认是 inplace,但加索引、改列类型仍可能锁表;PostgreSQL 虽支持并发创建索引,但 ADD COLUMN ... NOT NULL 仍需全表扫描。
- MySQL:用
pt-online-schema-change工具,它通过触发器双写 + 增量同步,全程不锁原表 - PostgreSQL:优先用
CREATE INDEX CONCURRENTLY;修改列默认值先ADD COLUMN再用后台 job 分批 update,最后ALTER COLUMN SET DEFAULT - 所有 DML 迁移(如数据清洗)必须加
WHERE id BETWEEN ? AND ?分页,配合FOR UPDATE SKIP LOCKED避免长事务阻塞复制
部署脚本里哪些信号和超时必须显式处理
自动化发布最常栽在“以为命令结束了,其实还在后台跑”——比如 docker-compose up -d 返回不代表容器 ready,systemctl start 返回也不代表服务已响应 HTTP。