一行日志引发的生产事故

生产事故

Posted by Kent on December 20, 2019

一行日志引发的生产事故

事故现象

发版后整个系统不可用,错误日志:Could not get JDBC Connection。

定位问题

  1. 根据错误日志首先想到的就是查看连接池信息,发现服务启动后,进行一些正常的业务流程操作, 连接池中的可用连接马上被用完,之后就出现了无法获取连接的错误日志了。

  2. 一边操作一边查看连接数,发现每次执行某个动作的时候,连接数就会+1,定位到问题可能出现的具体接口。

  3. 通过git查看当前版本修改的内容,发现相比上个版本多打了一行debug级别的日志。

    log.debug(JSON.toJSONString(dataSource));
    

原因

fastjson的toJSONString方法会调用对象中的Getter来获取对象的filed和value。 由于日志打印了dataSource,所以每打印一次就会调用一次getConnection方法,进而导致数据库连接耗尽。

总结

  • 不要轻易将一个不熟悉(了如指掌)的对象传入JSON.toJSONString()。
  • 即使是熟悉的类也尽量不要用JSON.toJSONString()来转成字符串,因为你不知道你的同事会在这个类里面写什么方法, 除非目标就是转成json字符串。
  • 尽量通过重写toString()来将对象转换成字符串,最原始的方法就是最简单的方法,最简单的方法就是安全的方法。