Ch6. リバースプロキシの利用
TL;DR
- リバースプロキシとは、ユーザーのリクエストを受け付け、アップストリームサーバーに転送するという、受け皿のような役割を持つものである
- パフォーマンスチューニングでは主に次のようなことを行う
- 転送時のデータ圧縮(gzipなど)
- リクエストとレスポンスのバッファリング
- リバースプロキシとアップストリームサーバーのコネクション管理
Q
- リバースプロキシとは何か
- リバースプロキシはどのように実装するのか
- nginxのアーキテクチャはどのようになっているのか
- 次を実現するためにはどうするのか
- 転送時のデータ圧縮
- リクエスト・レスポンスのバッファリング
- アップストリームサーバーとのコネクション管理
- TLS通信の高速化
R
リバースプロキシとは
- ユーザーのリクエストを受け付け、上位サーバー(アップストリームサーバー)に転送する仕組み
- 次の役割を持つ:
- 負荷分散
- コンテンツのキャッシュ
- HTTPS通信の終端
リバースプロキシはなぜ必要か
- プロセスとスレッドのアーキテクチャ構造が深く関わっている
- アプリサーバー:マルチプロセス・シングルスレッド
- 多数のプロセスを展開するとメモリ負荷が大きい
- クライアント数が多くなる(> 10000)と、コンテクストスイッチ(プロセスの切り替え)のためにパフォーマンスが急激に落ちる(C10K問題)
- アプリサーバー:マルチプロセス・シングルスレッド
アプリサーバーが直にリクエストを受け付けると、C10K問題により多数のユーザーを受け付けることが困難になるため、リバースプロキシによってこれを回避する必要があるから
nginxのアーキテクチャ
- マルチプロセス・シングルスレッド
- イベント駆動というアーキテクチャを使い、C10K問題を回避している
- 詳しくは独立した記事で書く
転送時のデータ圧縮を行う方法
- gzipを利用する
- HTTPクライアントがgzipに対応している場合に使うことができる(ほとんどのブラウザは対応している)
- gzipを使うことでレスポンスサイズを1/5程度に圧縮できる(小さいサイズだと逆に大きくなることがある)
- 静的ファイルは事前に圧縮しておくとnginxのCPU使用率を抑えることができる
- その他のファイルは圧縮率の設定を調整して、レスポンスサイズとCPU負荷のバランスを取ることが重要
- アプリサーバー上でもさらにgzip圧縮すると、ネットワークのコストを削減できる
gzip on;
:gzipの有効化gzip_types
:gzip圧縮するMIMEタイプを指定gzip_min_length
:gzip圧縮する最小のファイルサイズ
リクエスト・レスポンスのバッファリング
- 遅いクライアントがいるときに有効
- アプリサーバーのプロセスが占有されなくなるので、アプリ側で考えることが減る
アップストリームサーバーとのコネクション管理とは
- 大量のリクエストを受け付けるサーバーの場合、コネクションを頻繁に作り直すとパフォーマンスの低下や異常の原因になる
- キープアライブを有効化することで、コネクションを保持して使い回すことができる
- デフォルトでは都度切る設定になっている
Connection
ヘッダに空文字を渡すことで設定できるkeepalive_requests
でコネクションを閉じるまで受け付けるリクエスト数を設定できる
- キープアライブを有効化することで、コネクションを保持して使い回すことができる