Category : 開発

どうもWebサーバの調子が悪く、今週は四苦八苦していました。
ついでなので、サーバの状況を調べる方法をまとめてみました。
※ 参考にさせていただいたサイトは一番下に記述しています

目次

リソースの利用状況を調べる

top

$ top

top - 16:10:42 up 10:06,  2 users,  load average: 0.00, 0.01, 0.05
Tasks:  75 total,   1 running,  74 sleeping,   0 stopped,   0 zombie
%Cpu(s):  0.0 us,  0.0 sy,  0.0 ni, 99.7 id,  0.0 wa,  0.0 hi,  0.3 si,  0.0 st
KiB Mem:   1012128 total,   477528 used,   534600 free,    44504 buffers
KiB Swap:  1046524 total,        0 used,  1046524 free,   134900 cached

 PID USER      PR  NI  VIRT  RES  SHR S  %CPU %MEM    TIME+  COMMAND
 821 mysql     20   0  675m  52m 7272 S   0.3  5.3   0:31.19 mysqld
1065 root      20   0  163m 4672 3728 S   0.3  0.5   0:45.74 vmtoolsd
・・・
・・・
・・・

vmstat

$ vmstat 1

procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa
 2  0      0 534592  44512 134928    0    0     5     1   32  132  1  0 99  0
 0  0      0 534568  44520 134920    0    0     0    12   32   75  0  0 100  0
 0  0      0 534568  44520 134928    0    0     0     0   27   58  0  1 99  0
・・・
・・・
・・・

dstat

cpu、メモリ等の情報 + ディスクI/O、ネットワークI/Oなども一気にまとめて見る場合にはこちら。

# インストール
$ sudo yum install dstat

# 実行
$ dstat -Tclmdrn

--epoch--- ----total-cpu-usage---- ---load-avg--- ------memory-usage----- -dsk/total- --io/total- -net/total-
  epoch   |usr sys idl wai hiq siq| 1m   5m  15m | used  buff  cach  free| read  writ| read  writ| recv  send
1393744402|  1   0  99   0   0   0|   0 0.01 0.05| 295M 43.5M  132M  518M|4782B  912B|0.24  0.09 |   0     0 
1393744403|  0   0 100   0   0   0|   0 0.01 0.05| 295M 43.5M  132M  518M|   0     0 |   0     0 | 396B 1708B
1393744404|  0   0 100   0   0   0|   0 0.01 0.05| 295M 43.5M  132M  518M|   0     0 |   0     0 | 132B  580B
1393744405|  0   0 100   0   0   0|   0 0.01 0.05| 295M 43.5M  132M  518M|   0     0 |   0     0 | 132B  580B
1393744406|  0   0 100   0   0   0|   0 0.01 0.05| 295M 43.5M  132M  518M|   0     0 |   0     0 | 132B  580B
・・・
・・・
・・・

Nginxの接続状況確認

stub_statusを利用

“HttpStubStatusModule”モジュールを有効にします。

// 最近のNginxにはデフォルトで組み込まれている
// "--with-http_stub_status_module"が含まれていたらOK
$ nginx -V
nginx version: nginx/1.2.1
TLS SNI support enabled
configure arguments:・・・ --with-http_stub_status_module ・・・
# nginx.conf
server {
	listen 80;
	server_name localngcheck;

	location /nginx_status {
		stub_status on;
		access_log off;
		allow 127.0.0.1;
		deny all;
	}
}

allow 127.0.0.1 とすることで,サーバ内部からしか見れないようにします(環境によって適宜変更します)。また、私の環境ではlocalhostだと動かなかったので、hostsに下記のような追記をしました。

# /etc/hosts
127.0.0.1 localngcheck;

接続状況の取得は下記コマンドで。

$ wget -q -O - http://localngcheck/nginx_status

Active connections: 5 
server accepts handled requests
 136 136 219 
Reading: 0 Writing: 1 Waiting: 4 

stub_statusのモニタリング

いちいちコマンドを打つのではなく、vmstatみたいに定期的に数値が更新されるようにしてみます。
導入が最も簡単な “nginxstats.py” を利用してみます。

# ~/以下に適当なディレクトリを作成し、nginxstats.py をダウンロード
$ wget http://hostingfu.com/files/nginx/nginxstats.py
$ chmod +x nginxstats.py

# envのパスを確認します。
$ ls /usr/bin/env
/usr/bin/env

# pythonのパスが張れているか確認します。
$ which python
/usr/bin/python

実行してみます。デフォルトでは30秒に1回更新されます。必ずこのコマンドでの接続数1が発生します。

$ ./nginxstats.py http://localngcheck/nginx_status

Conn     Conn/s     Request/s  Read  Write Wait 
-------- ---------- ---------- ----- ----- -----
       4       0.13       0.27     0     1     3

また、nginxstats.pyファイルの中身にある下記を変更すると、更新時間を変更できます。

# nginxstats.py
TIME_SLEEP = 30

リクエスト制限(HttpLimitReqModuleの利用)

limit_req_zone、limit_req を設定します。

# limit_req_zone
limit_req_zone $binary_remote_addr  zone=[name]:[size] rate=[rate];

# $binary_remote_addr - 公式でこの変数名
# [name] - ゾーン名(公式では"one"という名称を使っている)
# [size] - ゾーンの最大サイズ
# [rate] - 毎秒/分/時 の最大リクエスト数。この数を超えると503を返す

# httpディレクティブ
# limit_req
limit_req zone=[name] burst=[burst];

# [name] - limit_req_zone で設定したnameを設定
# [burst] - limit_req_zoneの[rate]で設定した上限を超えた場合の待ち行列数。ここを設定しないと、[rate]を超えた瞬間すぐに503になってしまう。
# ※ この数値を超えたら503になる

# http、server、locationディレクティブ

nginxの設定ファイルに実際に追記してみます。

# nginx.conf
# limit_req_zoneはhttpディレクティブに設定
http {
	limit_req_zone $binary_remote_addr  zone=one:10m rate=50r/s;
	# 毎秒50リクエスト

	server {
		listen 80;
		server_name hogehoge.com;
		limit_req zone=one burst=100;
	}
}

負荷テスト

http_load を下記からダウンロードします。
[http://acme.com/software/http_load/](http://acme.com/software/http_load/)

# 適当に作業用ディレクトリを作成
$ cd ~
$ mkdir test
$ cd test

# testファイルにtarファイルを置く
# 展開してインストール
$ tar zxvf http_load-12mar2006.tar.gz
$ cd http_load-12mar2006

# makeにはsudoが必要かも
$ sudo make
$ sudo make install

http_load オプション

接続数

-parallel 数値
又は
-rate 数値
で指定。

parallel: 同時接続数の指定
rate: 毎秒ごとの新しい接続数の指定

接続回数

-fetches 数値
又は
-seconds 数値
で指定。
fetches: 接続する合計回数
seconds: 接続する秒数

実行コマンド例

$ http_load -verbose -parallel 10 -fetches 1000 [URLを記述したファイル名]

まとめ

dstatとnginxstats.pyが導入も簡単でとても便利です。
dstatでリソース/IO状況を見て、nginxstats.pyで同時接続数を見ながらhttp_loadで負荷テストをし、HttpLimitReqModuleの値を調整していく、という感じでしょうか。

EC2のmicroインスタンスはとても貧弱でアレですが、ギリギリを攻めることによって逆に勉強になります(白目)

参考サイト様一覧

リソース調査方法関連

stab_status関連

Nginxでリクエスト制限

負荷テスト関連