私が抱えていた問題
一部のサイトの読み込みに時間がかかるという問題がありました (「長い時間」とは、最大 16 秒を意味します)。場合によっては完全にタイムアウトし、Nginx 504 エラーが発生することがあります。通常、サイトがタイムアウトしたときに、サイトを再度リロードすると、すぐに読み込まれます。私が問題を抱えていたサイトは、トラフィック量が非常に少ない. 貧弱なコードが原因で発生する可能性のある速度低下を排除するために、Django 管理者インデックス ページを読み込んでサイトをテストしています。この特定のサイトは、スタッフ専用のイントラネット タイプのサイトであるため、Django 管理者のみを使用していることにも注意してください。
ホスティングのセットアップ
私がホストしているすべてのサイトは、2 つの Rackspace クラウド サーバー上にあります。最初のサーバーは 1024 MB の RAM を搭載したアプリ サーバーで、2 番目のサーバーは 2048 MB の RAM を搭載したデータベース サーバーです。アプリ サーバーは Nginx を使用して各サイトを提供しています。Nginx はすべての静的ファイルを提供し、その他すべてを各サイトの Django Gunicorn ワーカーにプロキシします。
データベース サーバーの RAM と CPU 負荷を見ると、データベース サーバー上ですべて問題ないように見えます。
$ free -m
total used free shared buffers cached
Mem: 1999 1597 402 0 200 1007
-/+ buffers/cache: 389 1610
Swap: 4094 0 4094
Top shows a CPU load average of: 0.00, 0.01, 0.05
何が起こっているのかをトラブルシューティングするために、アプリ サーバーのメモリ使用量を出力する簡単なスクリプトを作成しました。
匿名化されたサイト ドメインの出力例:
Celery: 23 MB
Gunicorn: 566 MB
Nginx: 8 MB
Redis: 684 KB
Other: 73 MB
total used free shared buffers cached
Mem: 993 906 87 0 19 62
-/+ buffers/cache: 824 169
Swap: 2047 828 1218
Gunicorn memory usage by webste:
site01.example.com 31 MB
site02.example.com 19 MB
site03.example.com 7 MB
site04.example.com 9 MB
site05.example.com 47 MB
site06.example.com 25 MB
site07.example.com 14 MB
site08.example.com 18 MB
site09.example.com 27 MB
site10.example.com 15 MB
site11.example.com 14 MB
site12.example.com 7 MB
site13.example.com 18 MB
site14.example.com 18 MB
site15.example.com 10 MB
site16.example.com 25 MB
site17.example.com 13 MB
site18.example.com 18 MB
site19.example.com 37 MB
site20.example.com 30 MB
site21.example.com 23 MB
site22.example.com 28 MB
site23.example.com 80 MB
site24.example.com 15 MB
site25.example.com 5 MB
Gunicorn 設定ファイルの例:
pidfile = '/var/run/gunicorn_example.com.pid'
proc_name = 'example.com'
workers = 1
bind = 'unix:/tmp/gunicorn_example.com.sock'
Nginx 構成の例:
upstream example_app_server {
server unix:/tmp/gunicorn_example.com.sock fail_timeout=0;
}
server {
listen 80;
server_name example.com;
access_log /var/log/nginx/example.com.access.log;
error_log /var/log/nginx/example.com.error.log;
location = /favicon.ico {
return 404;
}
location /static/ {
root /srv/sites/example/;
}
location /media/ {
root /srv/sites/example/;
}
location / {
proxy_pass http://example_app_server;
proxy_redirect off;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
client_max_body_size 10m;
}
}
ご覧のとおり、大量のメモリがスワップされているため、問題を修正するために、アプリ サーバーの RAM をアップグレードしました。これにより、サイトの速度が完全に修正されました。問題を修正することはできましたが、思ったよりも時間がかかり、サイトの速度低下の原因を基本的に推測していたように感じます. これらすべてが私の質問につながります...
質問
- トラフィックの少ないサイトでサイトの速度が遅いのは、サイトが非アクティブになったためにサイトが非アクティブになり、Gunicorn がサイトが非アクティブになった後に再度サイトをロードする必要があるためではないことをどのように判断できますか? サイトが非アクティブにならないようにする設定はありますか?
- メモリを大量に消費しているサイトがいくつかあるようです。サイトが使用しているメモリの量を減らすために使用できるツールは何ですか? Python プロファイリング ツールを使用する必要がありますか?
- スタック内のどのレベルでボトルネックが発生しているかを判断するために必要なツールと手順は何ですか?
- Gunicorn プロセスがスワップされているのか、それとも他のプロセスがスワップされているのかを判断する最良の方法は何ですか?
- 私がホストしているサイトのほとんどは大量のトラフィックを獲得していないため、Gunicorn ワーカーを 1 つだけ使用しています。サイトにある Gunicorn ワーカーの数を決定および調整するための、より科学的な方法はありますか?
- 同じサーバーで複数のサイトをホストする場合、メモリの使用量を減らすように構成する方法はありますか?