golang中的websocket服务器出现太多打开文件错误

时间:2016-11-28 18:53:29

标签: go websocket gorilla

我实际上是使用gorilla包将我的websocket服务器放在golang中。 如果我打开服务器,我每隔10天就会出现此错误。

2016/11/28 19:22:49 http: Accept error: accept tcp [::]:9001: accept4: too many open files; retrying in 1s
2016/11/28 19:22:50 http: Accept error: accept tcp [::]:9001: accept4: too many open files; retrying in 1s
2016/11/28 19:22:51 http: Accept error: accept tcp [::]:9001: accept4: too many open files; retrying in 1s
2016/11/28 19:22:52 http: Accept error: accept tcp [::]:9001: accept4: too many open files; retrying in 1s
2016/11/28 19:22:53 http: Accept error: accept tcp [::]:9001: accept4: too many open files; retrying in 1s
2016/11/28 19:22:54 http: Accept error: accept tcp [::]:9001: accept4: too many open files; retrying in 1s

这是我的代码:

func websocketHandler(writer http.ResponseWriter, request *http.Request){
    var socket *websocket.Conn
    user := new(user.User)
    user.Token = getParamURI(request.URL.RequestURI(), "token")

    if user.GetUserByToken() == false {

        errors := api.Error{}
        socket.Close()
        errors.ListErrors = append(errors.ListErrors, "Session doesn't exist")
        writer.Header().Set("Content-Type", "application/json")
        writer.WriteHeader(http.StatusNotAcceptable)
        json.NewEncoder(writer).Encode(errors)
        return

    }

    socket, _ = upgrader.Upgrade(writer, request, nil)

    err := make(chan string)

    go pingSocket(socket, err)
    go handleChangeNotification(socket, user.Id, err)
    go handleChangeMessage(socket, user.Id, err)
    for {
       tmp := <- err
        if len(tmp) > 0 {
            break
        }
    }
   socket.Close()
}

我的ulimit配置:

core file size          (blocks, -c) 0
data seg size           (kbytes, -d) unlimited
scheduling priority             (-e) 0
file size               (blocks, -f) unlimited
pending signals                 (-i) 7902
max locked memory       (kbytes, -l) 64
max memory size         (kbytes, -m) unlimited
open files                      (-n) 1024
pipe size            (512 bytes, -p) 8
POSIX message queues     (bytes, -q) 819200
real-time priority              (-r) 0
stack size              (kbytes, -s) 8192
cpu time               (seconds, -t) unlimited
max user processes              (-u) 7902
virtual memory          (kbytes, -v) unlimited
file locks                      (-x) unlimited

错误是相当难以理解的,我不明白,因为我在发生中断或错误的情况下关闭了套接字并且服务器正在生产中但在测试结束时有4-5个用户,所以它是不是限制。

有人可以告诉我错误的来源吗?

1 个答案:

答案 0 :(得分:2)

如果您关闭了所有身体状况并涵盖了所有其他可能的原因,那么如果您有高流量,则可能是极端问题。但通常你可以增加,即使你不是root用户,因为有两种类型的限制,即硬限制即。最大和软限制。您可以使用以下命令在Linux中检查它们:

# ulimit -Sn

# ulimit -Hn

如果软限制(Sn)低于硬限制(Hn)(默认值或由管理员设置),则可以使其高达硬限制。在我的所有CentOS安装中,我可以看到Sn的默认值为1024,Hn的默认值为4096,因此您可以轻松地将Sn最大化为4096,不涉及root用户。

如果可能,此功能将最大化打开文件的数量。复制/粘贴并在main func的开头调用maxOpenFile(),看看是否有帮助。

import "syscall"

func maxOpenFiles() {
    var rLimit syscall.Rlimit

    err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &rLimit)
    if err != nil {
        log.Println("Error Getting Rlimit ", err)
    }

    if rLimit.Cur < rLimit.Max {
        rLimit.Cur = rLimit.Max
        err = syscall.Setrlimit(syscall.RLIMIT_NOFILE, &rLimit)
        if err != nil {
            log.Println("Error Setting Rlimit ", err)
        }
    }
}

代码很简单,首先我们读取文件数量的当前设置,如果Cur小于Max,我们将其最大化。此func将仅将文件限制设置为当前的app / linux进程。