周日上了一次线,观察了流量和日志没发现问题,但是过了一会儿突然报警内存使用率超出阈值,赶紧查看原因。
在监控上观测到,有部分机器突发内存暴涨,内存使用率从22%突然增长至99%,很吓人,但是奇怪的是,这种突增的情况是偶然情况,只有一台机器出现。一开始小伙伴们认为是哪里内存泄漏了,但是我感觉不对,因为最近的代码没有什么危险和特殊代码,凭go自身的GC应该不至于内存泄漏才对,那么另一种可能性就很大了,不是内存泄漏,而是在极端条件下发生的会占用大量内存的业务逻辑导致的内存暴涨。
回忆起最近review的代码,貌似有一处有用到product全排列,然后就去了解那一块儿的业务逻辑,果然发现了,这块儿代码会对一块儿字符串进行全排列,并且由于上层业务并没有对字符串长度做限制,导致这个字符串可以很长很长,从而发生了此次极大的占用内存和cpu的情况。然后为了验证猜想,特意去测试服务器上试验了一下,果然输入了很长的字符串,确实导致了同样的情况发生。于是在进行全排列之前,对字符串做限制,超长部分直接截断。果然,如此修改之后内存暴涨问题就不再发生了。
此次事故提醒了我们,在写代码的时候,对于可能会让内存或cpu呈爆炸性指数增长的需求,一定要谨慎考虑,做出限制,否则难免发生线上事故。
网友评论