2017-11-03 7 views
0

私は以下のゴーランコードを持っています。それは自分のウェブサーバーの中で呼び出されたときにソケットを閉じないようです。これにより、「開いているファイルが多すぎます」というメッセージが表示されます。私はBody.Close()に関するすべてのことを読んできました。あなたが見ることができるように、それはそこにありますが、まだそれはまだ貧弱です。ゴランhttp.Postはオープンソケットを残す

接続処理について他に何か不足していますか?

func sendRequest(ctx context.Context, endpoint, uri string, data []byte) (int, []byte) { 
    reqID := requestIDFromContext(ctx) 
    // The servers have internally signed certs which are technically "not trusted" 
    tr := &http.Transport{ 
     TLSClientConfig: &tls.Config{InsecureSkipVerify: true}, 
    } 
    insecureclient := &http.Client{Transport: tr} 

    // Build the correct URL 
    url := endpoint + uri 

    requestbody := bytes.NewBuffer(data) 
    // Send our request and check for errors. 
    fmt.Println(reqID, "Forwarding request to URL:", url) 
    resp, err := insecureclient.Post(url, "application/json", requestbody) 
    if err != nil { 
     // This is where things happen when the connect goes bad 
     fmt.Println(reqID, err) 
     return 500, []byte("{}") 
     //return handleConnectionError(ctx, data, uri) 
    } 
    defer resp.Body.Close() 

    // Read response 
    responsebody, err := ioutil.ReadAll(resp.Body) 
    if err != nil { 
     fmt.Println(reqID, err) 
     responsebody = []byte("{}") 
    } 

    return resp.StatusCode, responsebody 
} 

FWIW、コードを変更すると、「真Request.Close =」と一緒に「http.NewRequest」とし、「insecureclient.Do」を使用して問題を解決するようです。

+0

再現可能な例を提供できれば、人々がコメントしやすくなります。あなたはこの問題を見てきましたか、アイドル状態の接続が時間内に閉じられていないことに関連している可能性がありますか? https://github.com/golang/go/issues/20166 –

+0

フルキープアライブ接続の再利用を許可することは、全身を読んで閉じることが重要です。サーバーはキープアライブをサポートしていますか?要求は同じエンドポイントにありますか? 'Client'と' Transport'の設定を調整しようとしましたか?タイムアウト、最大アイドル、キープアライブの無効化など? – Adrian

+2

ほとんどすべてがhttp/1.1またはhttp/2ですので、特別に閉じない限り、1回のリクエスト後にソケットを閉じる必要はありません。 – JimB

答えて

1

各クライアント(より正確にはトランスポート)は、独自の接続プールを維持します。これは、各sendRequest呼び出しの後にキープアライブで1つの接続が「ハングする」ことを意味します。毎回新しいクライアントを作成するのではなく、それを再利用してください。