问题描述

2018-12-15, 辅导服务一台服务器的 TCP 连接数忽上忽下(如下图), 上下浮动在400~500的数量. 而此时 CPU 一直在满负载, 内存占用很高(如下图). 导致用户无法正常上课.

问题缘由

1. TCP 连接中, 存在全球各地的 IP, 并且数量占比很高, 存在恶意攻击的可能.

2. 辅导服务会为每个 TCP 连接都会创建一个 ticker, 并且没有释放. time.NewTicker() → time.startTimer() → runtime.addtimer() → runtime.addtimerLocked() → runtime.timerproc() → runtime.siftdownTimer().

    每来一个 TCP 连接, ticker 会新增, timerproc 是唤醒处理定时器的一个函数. golang使用的最小堆维护的一个timer队列, go比较费时,每次操作最坏情况下都是logn(n为时间队列长度).

    新建了很多 ticker, 资源未释放, 导致内存占用过高.

经验教训

Never call time.NewTicker(…) within a fast iterating for loop.

Stop the ticker to release associated resources.

参考资料: