那些年,我因为"小改动"搞挂了生产环境

作为运维,最怕听到的一句话是什么?

不是"服务器崩了",不是"数据库丢了",而是——

"就改一下,很快的。"


故事一:配置文件的"小改动"

那天是周五下午,马上就要下班了。

开发小哥来了:"我改个配置文件,就改一行,帮我重启一下。"

我问:"改了什么?"

"就加了个参数,把超时时间从10秒改成30秒。"

我看了看配置文件,确实只是改了一个数字。

"测试环境试了吗?"

"试过了,没问题。"

我想着:改个数字而已,应该没事。

"好,重启吧。"

重启成功,服务正常运行。

开发小哥走了,我也准备下班。

刚走到楼下,手机响了。

监控告警:数据库连接数超过阈值。

回公司,打开监控,连接数飙升到1000。

"怎么回事?"

查日志,发现数据库查询超时了。

"为什么超时?"

查代码,开发小哥改了超时时间,从10秒改成30秒。

问题出在哪里呢?

原来,有一个批量查询的接口,每次查询1000条数据,原来的超时时间是10秒,因为查询太慢,所以超时失败,不会占用连接池。

现在超时时间改成30秒,查询不会超时,但会占用连接池30秒,而且这个接口调用频繁,所以连接池很快就被占满了。

"改回去。"

开发小哥:"好的,马上改。"

改回去,重启,连接数降下来了。

教训:

  • 改配置文件要考虑连锁反应
  • 测试环境和生产环境不一样(数据量、调用频率)
  • 不要相信"就改一下"

故事二:索引的"小改动"

又是周五下午,另一个开发小哥来了。

"我要给数据库加个索引,就加一个,很快。"

我问:"加在哪张表?哪个字段?"

"就user表的phone字段,查询太慢了。"

我问:"测试环境加了?"

"加了,查询快了很多。"

我想着:加个索引而已,应该没事。

"好,加吧。"

开始加索引,MySQL提示:"Adding index"。

我等着。

十分钟过去了,还在"Adding index"。

二十分钟过去了,还在"Adding index"。

三十分钟过去了,还在"Adding index"。

"怎么这么慢?"

开发小哥:"不知道啊,测试环境很快就加完了。"

我看了一下user表的行数:1亿行。

"测试环境有多少行?"

"1000行。"

我:"……"

终于,一个小时后,索引加完了。

但是,生产环境已经卡死了,所有的查询都变慢了。

为什么?

因为加索引的时候,MySQL会锁表,虽然加锁时间很短,但是索引创建需要时间,而且创建过程中会占用大量IO和CPU,导致整个数据库性能下降。

"删除索引。"

开发小哥:"好的,马上删除。"

删除索引,重启数据库,终于恢复正常。

教训:

  • 加索引要考虑数据量
  • 大表加索引要选在低峰期
  • 测试环境和生产环境的数据量差别很大

故事三:代码的"小改动"

这次不是周五,是周一上午。

产品经理来了:"我要改个小功能,改个逻辑,就改几行代码。"

我问:"改什么?"

"把订单状态从'待支付'改成'已支付',就是改个判断条件。"

我问:"测试环境测了?"

"测了,没问题。"

我看了代码,确实只是改了一个判断条件。

"好,发布吧。"

发布成功,订单状态确实改对了。

但是,第二天早上,发现了一个问题:对账系统对不上。

为什么?

原来,订单状态虽然改了,但是有一个定时任务,每天晚上会把"待支付"的订单取消,现在订单状态变成了"已支付",定时任务不会取消,但是支付系统没有收到钱,所以对账系统对不上。

"回滚代码。"

产品经理:"那这个功能怎么办?"

我说:"先把支付系统打通,再改状态。"

教训:

  • 改代码要考虑系统之间的依赖
  • 不要只看眼前,要看整体
  • 测试环境无法完全模拟生产环境的依赖关系

故事四:网络策略的"小改动"

这次是下午,开发小哥来了。

"我要开放一个端口,就一个端口,让内网访问。"

我问:"哪个端口?"

"8080端口,用来测试。"

我问:"测试环境呢?"

"测试环境已经开放了。"

我想着:开放一个端口而已,应该没事。

"好,开放吧。"

配置防火墙,开放8080端口。

开发小哥很高兴:"测试通了。"

但是,第二天,发现8080端口被人扫到了,然后被攻击了。

为什么?

因为8080是一个常用的Tomcat默认端口,容易被扫描到。

而且,开放了内网访问,意味着内网的任何机器都可以访问,包括一些不安全的机器。

"关闭端口。"

开发小哥:"那怎么测试?"

我说:"用VPN,或者配置白名单。"

教训:

  • 开放端口要考虑安全性
  • 不要相信"测试环境"的安全性
  • 内网不等于安全

故事五:日志级别的"小改动"

这次是晚上,开发小哥来了。

"我要改个日志级别,从ERROR改成DEBUG,就改一下,帮我看看问题。"

我问:"改哪个服务?"

"用户服务,有个问题,需要看详细日志。"

我想着:改个日志级别而已,应该没事。

"好,改吧。"

改了日志级别,重启服务。

开发小哥开始看日志。

但是,很快,磁盘告警了。

为什么?

因为DEBUG级别的日志会输出大量信息,包括每个请求的详细信息,每个查询的详细SQL,每个异常的堆栈信息。

而且,用户服务的访问量很大,所以日志量也很大,几分钟就写了几个GB。

"改回去。"

开发小哥:"那怎么看详细日志?"

我说:"只改一个实例的日志级别,或者只在测试环境看。"

教训:

  • 改日志级别要考虑磁盘空间
  • 高频服务的DEBUG日志会写很多
  • 不要在生产环境改太多实例的日志级别

最后

"小改动"真的小吗?

也许改的代码不多,也许改的配置很简单,也许改的时间不长。

但是,"小改动"往往隐藏着"大问题"。

因为:

  • 测试环境和生产环境不一样(数据量、调用频率、网络环境)
  • 系统之间有依赖关系,改一个地方可能影响其他地方
  • 一些看似简单的改动,可能会触发连锁反应

所以,以后有人对我说"就改一下,很快的",我会说:

"可以,但先写个变更申请,写清楚改什么、改为什么、有什么风险、怎么回滚。"

也许有人会说:"这么麻烦?"

我会说:"是的,但比搞挂了生产环境要好。"


Mr丶点心

2026-03-14

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注