计划任务而无内存泄漏

时间:2019-03-31 05:03:42

标签: go

我创建了一个调度程序,该调度程序使用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统计信息和容器日志如下。

Docker stats and container log

1 个答案:

答案 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 {

        }
    }