2016-11-28 83 views
0

我實際上使用gorilla軟件包將我的websocket服務器放入golang中。 如果我離開我的服務器,我每10天左右有一次這個錯誤。打開文件錯誤golang中的websocket服務器錯誤

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用戶的測試版接近,所以它不是限制。

有人能告訴我錯誤來自哪裏嗎?

+0

你確定'websocketHandler'在所有情況下都返回嗎?什麼是您的程序已打開的文件描述符?堆棧跟蹤顯示程序使用文件描述符做什麼? – JimB

+0

顯示從套接字讀取的代碼和發送到err通道的代碼。 –

+1

運行'netstat'查看打開的網絡連接,以防在其他地方出現問題(例如打開和關閉數據庫連接)。 –

回答

1

如果您已經關閉了所有人的活動並且覆蓋了所有其他可能的原因,那麼如果您擁有較高的流量,這可能是最大的問題。但通常你可以增加,即使你不是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) 
     } 
    } 
} 

代碼很簡單,首先我們先讀的文件的數量當前設置,如果薑黃素是小於MAX,我們最大出來。這個func只會將文件限制設置爲當前的app/linux進程。