Edited at

keepalive_requests in upstream context

先日、某所のnginxを1.14系から1.16系に更新したところ、レスポンスタイムが悪化する現象に遭遇したので、その時の対処記録。以下は99percentileと95percentileでのレイテンシのグラフ。


99percentile latency


95percentile latency

nginxのバージョンアップでレスポンスタイムが悪化するのを経験したのは初めてのことだったのですが、いろいろ調べてみるとアップストリームサーバとのキープアライブに関する挙動が大きく変わったのが原因で、そのへんのディレクティブの値をちょいと調整することで元のレスポンスタイムを維持できるようになりました。


keepalive_requests in upstream context

nginxの1.16系と1.14系の大きな違いの一つとしてkeepalive_requestsディレクティブが従来のhttp, server, locationコンテキストに加えてupstreamコンテキストでも利用できるようになったことが挙げられます。(実際に導入されたのは1.15.3)

https://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive_requests

また、同じタイミングでkeepalive_timeoutについてもupstreamコンテキストで利用可能になっています。

https://nginx.org/en/docs/http/ngx_http_upstream_module.html#keepalive_timeout

ただ、keepalive_requestsはデフォルト値が100になっているため、同時に大量のリクエストを捌くような環境ではアップストリームとの接続をキープアライブにする設定にしていても、頻繁にアップストリームとの接続が切れてしまいます。なので、そういった環境下ではかなり大きめの値にしておくのがよいでしょう。(nginxでアップストリームとのキープアライブを有効にする設定についてはこちらを参照)

upstream backend {

# upstream servers
# ...
keepalive 100;
keepalive_requests 10000;
}

実際に、keepalive_requestsを大きい値に設定することで元のレスポンスタイムに戻りました。


99percentile latency(再掲)


まとめ


  • nginx-1.16系ではupstreamコンテキストでkeepalive_requestsが利用できる


    • 実際に導入されたのは1.15.3



  • keepalive_requestsのデフォルト値(100)は同時に大量のリクエストを捌くような環境下では小さく、アップストリームとの再接続が頻繁に発生してレイテンシが悪化しやすいので、大きめの値を設定しよう


おまけ

ちなみに、上記のグラフはkazeburo/mackerel-plugin-axslogを使って出力しています。

秒間数千件以上のアクセスログでも高速に集計し、可視化できる mackerel-plugin-axslog の紹介