套接字:无限循环中 goroutines 的打开文件太多错误

socket: too many open files Error for goroutines in indefinite loop

我的程序要求无限期地向 datadog 发送指标(以便在 datadog 中持续监控应用程序)。程序运行一段时间后退出,报错“dial udp 127.0.0.1:18125: socket: too many open files”。

    func sendData(name []string, channel chan []string) {
      c, err := statsd.New("127.0.0.1:18125")
      if err != nil {
        log.Fatal(err)
      }

      v := versionDetails()
      tag := "tag:" + v
      final_tag := []string{dd_tags}
      appEpochTimeList := epochTime()
      rate := float64(1)

      for i, app := range name {
        e := c.Gauge(app, float64(appEpochTimeList[i]), final_tag , rate)
        if e != nil {
            log.Println(e)
            channel <- name
        }
        channel <- name
        log.Printf("Metrics Sent !!")
      }
  }

应用程序名称是从 config.toml 文件中读取的

问题出在您的 sendData() 函数上。此函数在您的 for 循环中调用并具有以下行:

c, err := statsd.New("127.0.0.1:18125")

此行将创建一个新的 DataDog 客户端,它使用 Unix 套接字。这解释了您的错误消息。

循环的每次迭代都会“分配”一个新套接字。经过足够数量的循环后,无法打开套接字,导致:

socket: too many open files

要解决此问题,您应该只创建一次客户端并将其作为参数传递给您的方法。

func sendData(client *statsd.Client, name []string, channel chan []string) {
    // do something with client...
}

func main() {
    client, err := statsd.New("127.0.0.1:18125")
    if err != nil {
        log.Fatal(err)
    }

    // do something else ...

    for res := range channel {
        go func(client *statsd.Client, appName []string) {
            time.Sleep(5 * time.Second)
            go sendData(client, appName, channel)
        }(client, res)
    }
}