我创建了一个调度程序,该调度程序使用golang newTicker每10秒运行一次。 每次滴答都会创建一个新的goroutine,该例程执行一些占用大量内存的任务,但要在10秒之前完成。
我已经在kubernetes中部署了它。容器同时具有调度程序和http服务器。 HTTP服务器将接受一个请求,并运行一次计划。这是用于重试手动错过的任务。代码如下:
func startScheduledTask() {
fmt.Println("Task Started...", time.Now())
ticker := time.NewTicker(10 * time.Second)
defer ticker.Stop()
for ; true; <-ticker.C {
go customTask(time.Now())
}
}
我观察到此代码没有释放内存。容器的Docker统计数据显示内存正在增长。尽管它在k8s上有内存限制,并且在OOMKilled的情况下k8s将重新启动,但是仍然错过了计划的任务,需要手动干预。有没有办法释放这种记忆?
customTask代码正在为每个刻度发出HTTP请求。
Docker统计信息和容器日志如下。
答案 0 :(得分:-2)
泄漏的goroutine是罪魁祸首。使用https://github.com/bcicen/grmon,发现goroutine的数量随着调度程序的滴答声而增加。他们正在等待net / http软件包。
response.body.close()和 Transport.CloseIdleConnections()解决了该问题。 NewTicker正常工作。谢谢
在进行http呼叫后,应修复此问题。
if err == nil && statusCode == http.StatusOK {
httpSuccess = true
//fmt.Println("httpSuccess", httpSuccess)
tr.CloseIdleConnections()
return response, nil
}
if response.Body != nil {
if err := response.Body.Close(); err != nil {
}
}