套接字:无限循环中 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)
}
}
我的程序要求无限期地向 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)
}
}