apacheで実行中のリクエストを見る

apacheで特定のプロセスが重いといった場合、どのようなRequestを処理しているかを知りたいことが多い。
アクセスログは処理完了後に出力されるため、その時点での状態を知る手段にはならない。

では、どのようにすればいいか?
mod_statusがある。
これはブラウザでアクセスするとapacheの状態を表示してくれる。
出力はHTMLなので、このままだと利用しにくい。
そこで出力結果を加工してコンソールからコマンドを叩けば状態を見れるようにする。

OSとかapacheのバージョンには依存しないと思う。
とにかくmod_statusが動けばいい。もしかするとhttpdのバージョンによってmod_statusの出力内容
が異なっているかもしれない。
念のために書いておくと、試したapacheはredhat5.8のhttpd-2.2.3-63.el5_8.1である。

まず、mod_statusを有効にし、httpd.confにある設定を有効にする。

<Location /server-status>
    SetHandler server-status
    Order deny,allow
    Deny from all
    Allow from 127.0.0.1
</Location>

今回作成したスクリプトを実行する。

# ./httpd_status.sh  | grep -E -v '(OPTIONS|jpg|js|png|gif|css|ico)'

     Srv    PID          Acc M   CPU %    SS   Req  Conn Child  Slot          Client             Vhost             Request
    1-57  10991  0/306/14534 _  7.95 %     0   860   0.0  2.94 88.53 125.174.156.148    www.aaaaaa.bbbb        GET /a/p
    2-57  24477   1/13/15227 C  0.40 %     1    15   0.0  0.07 98.66  126.16.193.239    www.aaaaaa.bbbb        GET /buy/ne
    3-57  21372  2/211/15098 C  5.03 %     0  2086   0.0  0.73 99.17     60.32.93.10    www.aaaaaa.bbbb        GET /buy/sear
    5-57  24490   1/74/14929 C  0.21 %     0   223   4.0  0.13 88.43  113.35.149.148    www.aaaaaa.bbbb        GET /top_ad
    8-57  24335   0/34/13089 _  0.37 %     0  3178   0.0  0.41 75.78   66.249.69.100    www.aaaaaa.bbbb        GET /rent/
   12-57  24206   0/88/14686 W  3.44 %     1     0   0.0  0.54 94.62  126.16.193.239    www.aaaaaa.bbbb        GET /buy/new_
   13-57  23539  0/161/13073 _  1.44 %     0  1912   0.0  0.78 78.71  119.63.196.124    www.aaaaaa.bbbb        GET /rent/search_list/0
   14-57  24521   1/10/12027 K  0.27 %     0   240   0.0  0.00 77.07  123.225.247.85    www.aaaaaa.bbbb        GET /buy/detail/
   66-57      -      0/0/264 .  4.57 %  1853     0   0.0  0.00  1.47    124.115.0.19    www.aaaaaa.bbbb        GET /invest/what.php
 

こんな感じで見える。
topで重いapacheのPIDは分かるので、そのPIDと同じPIDのRequestが実行中Requestである。

スクリプトはこんな感じ。コピー、ペーストして実行属性を付ければ動くはず。

#!/bin/sh
#
# 2012/05/10
# 現在実行中のhttpのRequestを取り出す
#
count=0
printf "%8s %6s %12s %1s %5s %5s %5s %5s %5s %6s %15s %20s %10s %s\n" "Srv" "PID" "Acc" "M" "CPU" "SS" "Req" "Conn" "Child" "Slot" "Client" "Vhost" "" "Request"
for list in `wget -q -O - http://127.0.0.1/server-status/ | \
    awk '{
        if( /table border/ ) { flg=1 }; \
        if( /\/table/ ){ flg=0 }; \
        if( flg==1 && $0 !~ /Conn|PID/ ){ gsub( / /,"!",$0 );gsub( /<[^>]*>/,"!",$0 ); print $0 }; \
    }'`;do
    line+=`echo -n $list  | sed 's/!/ /g'`
    count=`echo $count+1|bc`
    if [ $count -eq 3 ];then
        echo $line | awk '{ printf( "%8s %6s %12s %1s %5s %5% %5s %5s %5s %5s %5s %15s %20s %10s %s\n",$1,$2,$3,$4,$5,$6,$7,$8,$9,$10,$11,$12,$13,$14 )}'
        count=0
        line=""
    fi
done

# 実行コマンド
#./httpd_status.sh  | grep -E -v '(OPTIONS|jpg|js|png|gif|css|ico)'
#
 
Posted in apache, linux | Leave a comment

dotcloudに移転

自前サーバーで何でもやると言う時代はもうとっくに終わったんだろうと思う。
今後はPasSが全盛となると思うのだが、使ってみないことには評価もできないので
ブログをすべてdotcloudに移転した。

dotcloudにwordpressのソースをデプロイし、データベースのダンプをインポート
するとあっさり動いた。
さすがに太平洋を往復するだけあって、sshなんかは厳しいが、ブログの編集および
表示程度であれば、まったく問題ない。
少し時間がかかるかな・・・程度。

いつまで無料か分からないし、dotcloud自身がどうなるかも不明だが、このまま成長
を遂げてメジャーなサービスとなって欲しいと思う。

Posted in dotcloud | Leave a comment

nginxのlocation設定の優先順位について

最近nginxを使うことが多くなった。
ところがlocation設定が思い通りにできなかったで少し本気で取り組んでみた。

http://www.metainfo.jp/info/phpinfo.php 

へのアクセスを想定する。同一サーバー内でapcheが動いていて、そこでPHPも動くとする。
nginxのconfには以下のようにlocationを書く。
正規表現で複数マッチする場合どっちが有効か。

location ~ /info/ {
    auth_basic           "basic";
    auth_basic_user_file "/var/www/auth/.nginx-test";

    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;

    proxy_pass  http://127.0.0.1:80;
}

location ~ /info/ {
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;

    proxy_pass  http://127.0.0.1:80;
}

先にマッチした方なので、認証有りになる。

では前方一致の場合は

location ^~ /info/ {
    auth_basic           "basic";
    auth_basic_user_file "/var/www/auth/.nginx-test";

    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;

    proxy_pass  http://127.0.0.1:80;
}

location ~ /info/ {
    proxy_set_header X-Real-IP  $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header Host $http_host;

    proxy_pass  http://127.0.0.1:80;
}

前方一致が優先なので、この場合も認証有りになる。

さて、先の記述だとすべてのアクセスがapacheに振られることになるが、画像は普通にnginxから出したいとする。
locationの中にlocationが書ければ解決する。

location ~ /info/ {
    auth_basic           "basic";
    auth_basic_user_file "/var/www/auth/.nginx-test";

    # phpとcgiの処理はapacheへ転送
    # /以降で何か一文字が繰り返し、ドットでphpかcgiという意味
    location ~ /.*\.(php|cgi) {
        proxy_set_header X-Real-IP  $remote_addr;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Host $http_host;

        proxy_pass  http://127.0.0.1:80;
    }
    # phpとcgi以外はそのままnginxで処理
}

locationの中にlocationが書けると知らなくて相当悩んだ。
ここにも若干制限があって、

location = hoge {
}

のように= でマッチさせた場合、locationの中にlocationは書けない。
=以外の ~ もしくは ^~ の場合は大丈夫で、locationの中にlocationを書くことができる。

なお、テストしたバージョンは1.0.12です。

Posted in linux, nginx | Leave a comment