मुझे अपने प्रोग्राम में डेटाडॉग को अनिश्चित काल तक मेट्रिक्स भेजने की आवश्यकता है (डेटाडॉग में निरंतर ऐप मॉनिटरिंग के लिए)। प्रोग्राम कुछ समय के लिए चलता है और त्रुटि "डायल udp 127.0.0.1:18125: सॉकेट: बहुत अधिक खुली फ़ाइलें" के साथ बाहर निकलता है।

    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 फ़ाइल से पढ़े जाते हैं

-1
Shatabdi Pal 27 नवम्बर 2020, 22:12

1 उत्तर

सबसे बढ़िया उत्तर

समस्या आपका sendData() फ़ंक्शन है। इस फ़ंक्शन को आपके लूप के लिए कहा जाता है और इसमें निम्न पंक्ति होती है:

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

यह लाइन एक नया डेटाडॉग क्लाइंट बनाएगी, जो यूनिक्स सॉकेट का उपयोग करता है। यह आपके त्रुटि संदेश की व्याख्या करता है।

आपके लूप के प्रत्येक पुनरावृत्ति के साथ, एक नया सॉकेट "आवंटित" होता है। पर्याप्त मात्रा में लूप के बाद कोई सॉकेट नहीं खोला जा सकता है, जिसके परिणामस्वरूप:

सॉकेट: बहुत अधिक खुली फ़ाइलें

इसे ठीक करने के लिए आपको केवल एक बार क्लाइंट बनाना चाहिए और इसे पैरामीटर के रूप में अपनी विधि में पास करना चाहिए।

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)
    }
}
1
Shatabdi Pal 28 नवम्बर 2020, 02:23