2015-09-01 15 views
5

Hier ist eine einfache Go http (TCP) -Verbindung TestskriptGo, tcp zu viele offene Dateien debuggen

func main() { 
    ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { 
     fmt.Fprintln(w, "Hello, client") 
    })) 
    defer ts.Close() 
    var wg sync.WaitGroup 
    for i := 0; i < 2000; i++ { 
     wg.Add(1) 
     go func(i int) { 
      defer wg.Done() 
      resp, err := http.Get(ts.URL) 
      if err != nil { 
       panic(err) 
      } 
      greeting, err := ioutil.ReadAll(resp.Body) 
      resp.Body.Close() 
      if err != nil { 
       panic(err) 
      } 
      fmt.Printf("%s", i, greeting) 
     }(i) 
    } 
    wg.Wait() 
} 

Und Wenn ich das ich in Ubuntu laufen bekommen:

panic: Get http://127.0.0.1:33202: dial tcp 127.0.0.1:33202: too many open files

Weitere Beiträge sagen Sie, um sicherzustellen, Close die Verbindung, die ich hier alles mache. Und andere sagen, die Grenze der maximalen Verbindung mit ulimit zu erhöhen oder sudo sysctl -w fs.inotify.max_user_watches=100000 versuchen, aber immer noch nicht funktioniert.

Wie kann ich Millionen von TCP-Verbindungs-Goroutines auf einem einzigen Server ausführen? Es stürzt nur mit 2.000 Verbindungen ab.

Danke,

Antwort

15

Ich glaube, Sie Ihren max Dateideskriptoren ändern müssen. Ich habe das selbe Problem auf einer meiner Entwicklungs-VMs schon einmal kennengelernt und musste die Dateideskriptoren max ändern, nicht irgendetwas mit inotify-Einstellungen.

FWIW, Ihr Programm läuft gut auf meiner VM.

·> ulimit -n 
120000 

Aber nachdem ich

·> ulimit -n 500 
·> ulimit -n 
500 

laufen erhalte ich:

panic: Get http://127.0.0.1:51227: dial tcp 127.0.0.1:51227: socket: too many open files 
-1

ich auch die enge Verbindung Header manuell einstellen musste, um den Dateideskriptor Problem zu vermeiden:

r, _ := http.NewRequest(http.MethodDelete, url, nil) 
r.Close = true 
res, err := c.Do(r) 
res.Body.Close(); 

Ohne r.Close = wahr a nd res.Body.Close() Ich drücke die Datei Deskriptor Grenze. Mit beiden konnte ich so viele abfeuern, wie ich brauchte.

+2

Dies doesn Es scheint nicht zu funktionieren. – shicky

+0

das funktioniert nicht! – Ankita

0

zu können in Ihrer Funktion goruntine, versuchen Sie diesen https://github.com/leenanxi/nasync

//it has a simple usage 
nasync.Do(yourAsyncTask) 

im Code

for i := 0; i < 2000; i++ { 
    nasync.Do(func() { 
     resp, err := http.Get("https://www.baidu.com") 
     ... 
    }) 
} 

der Standard max geht goruntine in nasync lib ist 1000

+0

diese lib funktioniert, und es ist am meisten weniger ressourcenintensive async lib – lee

0

Änderung der ulimit zu vermeiden der Fehler "zu viele offene Dateien" standardmäßig Max ulimit ist 4096 für Linux und 1024 für Mac, können Sie c hange ulimit bis 4096 durch Eingabe von ulimit -n 4096 für über 4096 müssen Sie limits.conf in etc/security folder für linux ändern und feste Grenze auf 100000 setzen, indem Sie diese Zeile "* hard core 100000" hinzufügen

Verwandte Themen