2019 03 21
事故类型
局部故障(全部客户 的 station 模块不可用)
事故过程
- 14:36,收到腾讯云的报警邮件,A1-station-worker-1/2 的内存超过 70%。可惜没有引起注意
- 14:40,同时收到各种报警:
- [阿里云] station nginx 长耗时告警
- [阿里云] a1-webnginx-access-500
- [5xx监测脚本电话报警] 34 个客户的 station 出现 5xx 报警
- 发现 A1-station-worker-1/2 的内存耗尽
- 发现在过去的 30 分钟内,发布了三个 station 工程的全量,猜测是因为全量太多导致内存耗尽
- 开始清理 A1-station-worker-1/2 上没有流量的 uwsgi workers
- 在清理 uwsgi 进程的过程中,A2切流量脚本根据预设的逻辑更改了 lb-nginx-1/2 的 nginx 配置,将流量切到了 A2. 但是在年后切完 MySQL 数据库直到现在,A2 的服务一直处于不可用的状态,所以切流量脚本的行为反而加重了事故,现在 station 处于全局不可用的状态。
- 通过切流量脚本留下的配置文件备份,开始人工修改 lb-nginx-1/2 的配置,将流量切回 A1
- 流量切回 A1 后,uwsgi workers 也清理完毕,服务恢复
事故时长
8 分钟 (14:39 - 14:47)
事故原因
- 发布全量后没有清理旧全量进程,下午在半小时那发布了三个全量,加上一开始的全量,相当于有四个分支在运行。每个worker占用200M内存 * 每个分支最少10个worker * 4个分支 = 8G 内存,直接把两台服务器的内存占满了。
- A2 处于不可用状态后,没有关闭自动切流量脚本,导致加重了事故。
解决思路
对发布脚本做出下面的改动:
- 以前发布脚本在 release 和 complete 之前有全局锁,现在需要把这个锁提前到 prerelease。这样只有某一个 prerelease 分支 complete 之后,用户才能使用发布脚本执行其他 prerelease 操作,从而保证了有且仅有一个 prerelease 分支,防止多个 prerelease 分支占用了过多内存。
- 在 release 之后,发布脚本自动地清理以前的全量工程,防止老的全量分支占用过多内存。