Closed1

Golang における大量リクエストを捌く為に対応すべきこと

yuyake0084yuyake0084

概要

Golang で大量にリクエストを捌いていると、突如下記のようなエラーが発生する。

Get "{接続先URL}": dial tcp {接続先IP}:{接続先Port}: connect: cannot assign requested address

これは TCP に於ける TIME_WAIT の状態となったコネクションが大量に残り続けたことで利用可能なファイルディスクリプタが枯渇してしまうことで発生するエラーで、これによって外部の DB や API に接続することができなってしまう。

なお、以下コマンドを API サーバーなどで実行すればが詳細な状況が把握できる。

TCP/IPの通信状況を確認

$ watch -n 1 'netstat -tanu | sed -E "s/  +/,/g" | cut -d"," -f4-5 | sort | uniq -c'

利用可能なファイルディスクリプタ数を確認

$ ulimit -n

結論

MaxIdleConns と MaxIdleConnsPerHost を指定する。

httpClient := &http.Client{
    Transport: &http.Transport{
        MaxIdleConnsPerHost: 200,
        MaxIdleConns:        0,
    },
}
パラメータ名 概要
MaxIdleConnsPerHost ホストごとでアイドルさせるコネクションの上限値。デフォルト値は2。
MaxIdleConns Transport 全体で保持できる空きコネクションプールの最大値。デフォルト値は100。

MaxIdleConnsPerHost でホストごとでアイドルさせるコネクションの上限値を引き上げて、MaxIdleConns を0にすることで保持できるコネクションプールを無制限とすることが可能。

参考文献

https://belonginc.dev/members/mohiro/posts/http-default-client

https://syossan.hateblo.jp/entry/2018/05/31/082919

https://qiita.com/kiririmode/items/6b33aaf1b900d28de704

このスクラップは2024/01/31にクローズされました