You need to reuse the client http transport or you will run out of connections at the os level due to them being in a closed wait state.
> On Mar 11, 2019, at 4:56 AM, Javier <xle...@gmail.com> wrote: > > Hi > > I am load testing a simple application that calls an echo service with a GET. > My application is tested with ab tool and the load is 500 concurrent > connections with 50000 requests. > > The application is failing after a while because i/o errors that I assume are > related to the client connection pool. > I have set the pool to 10000 after check with netstat the number of > connections in wait status created by my app. It worked fine at home (in > windows and in my macbook) but failed in a Linux server at work. > > I am wondering how to properly set limits in client to prevent my application > to stop due to errors or even how to monitor and trace how many connections > of the pool are used and their status.. (is it possible). > > My application is doing this (just relevant parts of the code) > > > > // Handle iterative path and calls iterative calculation service > func echoHandler(calledServiceURL string, netClient *http.Client) func(w > http.ResponseWriter, r *http.Request) { > return func(w http.ResponseWriter, r *http.Request) { > > params := mux.Vars(r) > > url := calledServiceURL + "/echo/" + params["message"] > > req, reqErr := http.NewRequest("GET", url, nil) > if reqErr != nil { > log.Fatal("Error en response: ", reqErr) > fmt.Fprintf(w, "Error en response: %s", reqErr) > return > } > > req.Header.Set("Connection", "close") > //req.Header.Set("Connection", "Keep-Alive") > > resp, err := netClient.Do(req) > if err != nil { > log.Fatal("Error en response: ", err) > fmt.Fprintf(w, "Error en response: %s", err) > return > } > > respData, errResp := ioutil.ReadAll(resp.Body) > resp.Body.Close() > if errResp != nil { > log.Fatal("Error en RespData", errResp) > fmt.Fprintf(w, "Error en respData: %s", err) > return > } > > fmt.Fprintf(w, "%s", respData) > > } > } > > > // Define just one transport for all calls > tr := &http.Transport{ > MaxIdleConns: 10000, // iddle conn pool size > MaxIdleConnsPerHost: 10000, // iddle conn pool size per host > DisableKeepAlives: true, // disable keep alive > } > > netClient := &http.Client{Transport: tr} > > router := mux.NewRouter() > > router.HandleFunc("/", Index).Methods("GET") > router.HandleFunc("/echo/{message}", > echoHandler(viper.GetString("calledServiceURL"), > netClient)).Methods("GET") > > srv := &http.Server{ > Addr: viper.GetString("port"), > // > https://stackoverflow.com/questions/29334407/creating-an-idle-timeout-in-go > //WriteTimeout: time.Second * 60, > ReadTimeout: time.Second * 15, > //IdleTimeout: time.Second * 120, > //Handler: router, // Pass our instance of gorilla/mux in. > Handler: router, > } > > // Run our server in a goroutine so that it doesn't block. > go func() { > log.Println("Running server....") > > if err := srv.ListenAndServe(); err != nil { > log.Println(err) > } > }() > > c := make(chan os.Signal, 1) > // We'll accept graceful shutdowns when quit via SIGINT (Ctrl+C) > // SIGKILL, SIGQUIT or SIGTERM (Ctrl+/) will not be caught. > signal.Notify(c, os.Interrupt) > > // Block until we receive our signal. > <-c > > > ctx, cancel := context.WithTimeout(context.Background(), time.Second*3) > defer cancel() > > srv.Shutdown(ctx) > fmt.Println("\n\n") > log.Println("shutting down") > log.Println("Goddbye!....") > os.Exit(0) > > > Thanks in advance > J > -- > You received this message because you are subscribed to the Google Groups > "golang-nuts" group. > To unsubscribe from this group and stop receiving emails from it, send an > email to golang-nuts+unsubscr...@googlegroups.com. > For more options, visit https://groups.google.com/d/optout. -- You received this message because you are subscribed to the Google Groups "golang-nuts" group. To unsubscribe from this group and stop receiving emails from it, send an email to golang-nuts+unsubscr...@googlegroups.com. For more options, visit https://groups.google.com/d/optout.