2016-11-28 8 views
0

私は実際にgolillaパッケージを使用して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

ボディリベアをすべて閉じ、その他の理由をすべてカバーしている場合は、高トラフィックの場合はulimit問題になる可能性があります。しかし、通常、ハード・リミットの2つのタイプがあるので、ルート・ユーザでない場合でも、それを増やすことができます。最大、およびソフトリミット。ソフトリミット(Snが)ハードリミット(HN)(デフォルトまたは管理者によって設定される)よりも低い場合は、あなたがそれを行うことができます

# ulimit -Sn

# ulimit -Hn

を:あなたが使用してLinuxでそれらの両方を確認することができますハード限界まで高くなる。私のCentOSのすべてのインストールでは、Snが1024、Hnが4096であることがわかるので、Snを4096まで簡単に最大化できます。rootユーザーは含まれません。

可能であれば、開いているファイルの数を最大にします。メインの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より小さい場合は最大値にします。この関数は、現在のapp/linuxプロセスに対してのみファイル制限を設定します。

関連する問題