I am running a Go binary that has an http server with systemd. I have it setup so that Caddy has a reverse-proxy to this go http server.
http: Accept error: accept tcp [::]:8002: accept4: too many open files;
dial tcp 192.85.2.4:443: socket: too many open files
When I look at the open files of the process, I get 1025 or less, though my ulimit is set to a much larger limit:
$ lsof -p 1243 | wc -l
1025
$ ulimit -Sn
200000
$ ulimit -Hn
1048576
I'm not sure if that's the problem but seems that it could be? Seems like the Go server should be spawning new goroutines or take care of that somehow.
EDIT: Here's my server script:
package main
import (
"fmt"
"time"
"net/http"
)
type Config struct{}
func (c Config) testerHandler(w http.ResponseWriter, r http.Request) {
r.Body.Close()
time.Sleep(1 * time.Second)
fmt.Fprintf(w, "hello\n")
}
func main() {
c := &Config{}
http.HandleFunc("/tester", c.testerHandler)
fmt.Println("listening on http://127.0.0.1:8000")
http.ListenAndServe(":8000", nil)
}
EDIT: And here's a script I use to spam my server:
package main
import (
"log"
"net/http"
)
func main() {
number := 10000
log.Printf("spamming %d numbers\n", number)
ch := make(chan interface{})
client := http.Client{}
for i:=0; i<number; i++{
go func(number int) {
u := "http://127.0.0.1:8000/tester"
rsp, err := client.Get(u)
if err != nil {
ch <- err
return
}
rsp.Body.Close()
ch <- rsp
}(number)
}
var errs int
m := make(map[int]int)
for i:=0; i<number; i++ {
rsp := <-ch
switch rsp.(type) {
case *http.Response:
code := rsp.(*http.Response).StatusCode
m[code]++
default:
log.Println(rsp.(error))
errs++
}
}
log.Println("errs:", errs)
for k, v := range m {
log.Printf("%d:%d\n", k, v)
}
}