socket: too many open files
maengsanha opened this issue · 0 comments
maengsanha commented
package main
import (
"fmt"
"net/http"
"os"
"runtime"
"strconv"
"strings"
"sync"
"sync/atomic"
)
// check NOFILE Limit
// ulimit -Hn
// ulimit -Sn
// ulimit -n count
// or
// sudo vi /etc/security/limits.conf (in root account)
// * hard nofile 500000
// * soft nofile 500000
// root hard nofile 500000
// root soft nofile 500000
var messages, codes sync.Map
func main() {
url := fmt.Sprintf("http://%s", os.Args[1])
count, _ := strconv.Atoi(os.Args[2])
// since go 1.5, default GOMAXPROCS equals to NumCPU
// runtime.GOMAXPROCS(runtime.NumCPU())
fmt.Printf("using %d cores\n", runtime.GOMAXPROCS(0))
fmt.Printf("%s\n\n", strings.Repeat("=", 50))
var nReq int
for nReq = 1; nReq <= count; nReq <<= 1 {
fmt.Printf("sending concurrent requests %d times\n", nReq)
nFail := stress(url, nReq)
fmt.Printf("failure rate: %f%% (%d/%d)\n\n", float64(nFail)/float64(nReq), nFail, nReq)
}
if nReq != count << 1 {
fmt.Printf("sending concurrent requests %d times\n", count)
nFail := stress(url, count)
fmt.Printf("failure rate: %f%% (%d/%d)\n\n", float64(nFail)/float64(count), nFail, count)
}
fmt.Printf("%s\n\n", strings.Repeat("=", 50))
fmt.Println("error messages\n")
messages.Range(func(k, v interface{}) bool {
fmt.Println(k)
return true
})
fmt.Printf("\n%s\n\n", strings.Repeat("=", 50))
fmt.Println("error codes\n")
codes.Range(func(k, v interface{}) bool {
fmt.Println(k)
return true
})
}
func stress(url string, nReq int) (nFail int64) {
var syncer sync.WaitGroup
syncer.Add(nReq)
for i := 0; i < nReq; i++ {
go func() {
defer syncer.Done()
resp, err := http.Get(url)
if err != nil {
atomic.AddInt64(&nFail, 1)
messages.Store(err, struct{}{})
return
}
defer resp.Body.Close() /* mistake! should close the response body */
if resp.StatusCode != http.StatusOK {
atomic.AddInt64(&nFail, 1)
codes.Store(resp.StatusCode, struct{}{})
return
}
}()
}
syncer.Wait()
return
}