Slide 1

Slide 1 text

Plack web application ͷϩάͷ࿩ Gotanda.pm #5 LT すずきまさし / @masasuz 2015/06/24 1

Slide 2

Slide 2 text

おまえだれよ すずきまさし / @masasuz 五反田の辺りにある中小web企業 開発/運用基盤的整備 社内システム開発 zsh / perl / MySQL / Ubuntu / Debian / i☆Ris 2

Slide 3

Slide 3 text

Web applicationの チューニングまず何する? 3

Slide 4

Slide 4 text

重そうな処理を とりあえず、直そう! 4

Slide 5

Slide 5 text

重そうな処理をとりあ えず、直そう! 5

Slide 6

Slide 6 text

ボトルネックは 推測しないでください。 計測してください。 6

Slide 7

Slide 7 text

今回は業務を通して得たWeb Applicationのアクセスログに関する知 見に関して発表します。 高速化を考えるための下回りの話です。 具体的なアクセスログの解析方法とか にはあまり触れません 7

Slide 8

Slide 8 text

もくじ 計測のための材料 アクセスログ 計測を捗らせる道具 Fluentd, Elasticsearch, Kibana4 まとめ 8

Slide 9

Slide 9 text

計測のための材料 ログ アクセスログ エラーログ イベントログ(アプリケーションログ) 各種ミドルウェアのスローログ etc... 統計情報 sar リソースグラフ(e.g cloudforecast) 負荷情報 ps, top, dstat, mpstatl, iostat, etc... 9

Slide 10

Slide 10 text

計測のための材料 ログ アクセスログ <= 今回はこれ エラーログ イベントログ(アプリケーションログ) 各種ミドルウェアのスローログ etc... 統計情報 sar リソースグラフ(e.g cloudforecast) 負荷情報 ps, top, dstat, mpstatl, iostat, etc... 10

Slide 11

Slide 11 text

アクセスログ 計測するための指標はさまざまありま すが、今回はアクセスログについて見 ていきます。 webアプリケーションの基本的な処理単 位はアクセス毎なので、どのパスのア クセスが多いのか、どのパスの処理に 時間がかかってるのかを見るところか らボトルネックの探しを始めて行くと 良いでしょう。 11

Slide 12

Slide 12 text

アクセスログが 出力される場所 アプリケーションサーバ Plack, Rack, mod_perl etc... リバースプロキシ Apache, Nginx, Perlbal etx... 本当に小規模なアプリならリバースプ ロキシが無い場合もあるでしょう 12

Slide 13

Slide 13 text

簡単な webアーキテクチャ 13

Slide 14

Slide 14 text

アプリケーション1台 男前アーキテクチャ 14 インターネット アプリケーションサーバ

Slide 15

Slide 15 text

リバースプロキシ 一般的なアーキテクチャ 15 インターネット アプリケーションサーバ リバースプロキシ

Slide 16

Slide 16 text

ログの項目1 16 nginx apache vhost $host %{Host}i host $remote_addr %h uri $request_uri %U%q method $request_method %m protocol $server_protocol %H status $status %>s size (response) $body_bytes_sent %B reqsize (request) $request_length %I

Slide 17

Slide 17 text

ログの項目2 17 nginx apache referer $http_referer %{Referere}i ua $http_user_agent %{User-agent}i reqtime $request_time %T apptime $upstream_respon se_time runtime $upstream_http_x_ runtime %{X-Runtime}o

Slide 18

Slide 18 text

時間の指標 reqtime リクエストを受け取ってからクライアントに返すまでに かかった時間 apptime リバースプロキシ先からレスポンスをもらうまでにかかっ た時間 runtime アプリケーションがアクセスに対してかかった処理時間 Plack::Middleware::Runtimeが必要 18

Slide 19

Slide 19 text

リバースプロキシ視点 のそれぞれの時間 19 reqtime apptime runtime アプリケーションサーバ リバースプロキシ

Slide 20

Slide 20 text

ログのフォーマット フォーマット combined LTSV Line Delimited JSON 新規で選ぶのであれば、プログラムでパースしやすいLTSV かJSONが良い 個人的にはLTSVがいろいろやりやすいのでLTSVで紹介しま す 20

Slide 21

Slide 21 text

ログを出力する(Nginx) 21 log_format ltsv_log 'time:$time_iso8601\t' 'host:$remote_addr\t' 'vhost:$host\t' 'user:$remote_user\t' 'upstream:$upstream_addr\t' 'method:$request_method\t' 'protocol:$server_protocol\t' 'uri:$request_uri\t' 'status:$status\t' 'ua:$http_user_agent\t' 'referer:$http_referer\t' 'size:$bytes_sent\t' 'reqsize:$request_length\t' 'reqtime:$request_time\t' 'apptime:$upstream_response_time\t' 'runtime:$upstream_http_x_runtime\t'; access_log /var/log/nginx/access.log ltsv_log;

Slide 22

Slide 22 text

ログを出力する(Plack) Plack::Middleware::AccessLog 標準 Plack::Middleware::AxsLog かつては速かった エラーなログのみ出力や一定以上のレ スポンスタイムがかかったログのみ出 力ができる 22

Slide 23

Slide 23 text

ログを出力する(Plack) 23 use File::Spec::Functions qw(catfile); use File::RotateLogs; $logger = File::RotateLogs->new( logfile => catfile('/var/log/plack', "$project_name.access.%Y_%m%d.log"), linkname => catfile('/var/log/plack', "$project_name.access.log"), ); enable 'AxsLog', logger => sub { $logger->print(shift); }, error_only => ($ENV{PLACK_ENV} || '') eq 'production' ? 1 : 0, long_response_time => ($ENV{PLACK_ENV} || '') eq 'production' ? 0.3 : 0, format => join( "\t", 'time:%{%Y-%m-%dT%H:%M:%S%z}t', 'host:%h', 'vhost:%{Host}i', 'user:%u', 'method:%m', 'protocol:%H', 'uri:%U%q', 'status:%>s', 'ua:%{User-agent}i', 'referer:%{Referer}i', 'size:%b', 'retime:%T', 'runtime:%{X-Runtime}o', 'pid:%P', );

Slide 24

Slide 24 text

ログを集計してみる シェルスクリプト最高!!!!!!!! LTSVフォーマットであれば、これだけで、vhostご と、pathごとのアクセス数を出せる。 少しワンライナー書いてあげるだけで、色々集計 出来る。けど、、 24 % cut -f 3,8 /var/log/nginx/access.log | ¥ sed -r -e 's/(uri:[^?]+)(¥?.+)?/$1/' | ¥ sort | ¥ uniq -c | ¥ sort -nr | ¥ head -20

Slide 25

Slide 25 text

けどね。 複数ホスト集計したいとき面倒じゃな いか。 本番サーバに入ってコマンド叩くの??? 25

Slide 26

Slide 26 text

ログ収集だ Fluentd ざっくり言うとログ収集ツール 様々なinput/output pluginを組み合わせて、 ログ転送/集約ができる fluentdでログサーバにアクセスログを転送し てそれを一つのログ(もしくはvhostごとのロ グ)に集約出来る。 見る場所を1つにできる 26

Slide 27

Slide 27 text

Fluentdによるログ転送 27 1.in_tail アクセスログを読み込む access log access log 2.(in|out)_forward 転送する 4.out_file 集約したログを出力 webサーバ群 ログ集約サーバ 3.ログを集約する

Slide 28

Slide 28 text

Fluentdの効用 ログサーバに行けば、集約されたログ を見ることができるようになった。 ここではファイルに吐き出してますが、 fluentdのoutputをMySQLやMongoDBに変 えてあげることでシェルスクリプトよ り柔軟に集計ができるようになります。 28

Slide 29

Slide 29 text

もう少し可視化したい ログの集計をかければスナップショッ トとしての情報は見れるけど、値の遷 移や傾向も見たい。 手段 Growthforcast Elasticsearch + kibana4 29

Slide 30

Slide 30 text

Growthforecast numericcounterでruntime毎に集計して、Growforecast にpost。 お手軽にデータをグラフ化できる。 dataconterでstatus codeの集計なども可能。 30

Slide 31

Slide 31 text

Growthforecast 悪くないけど 過去データが挿入しにくい グラフだけと割り切るなら良い 負荷が若干高い 負荷軽減のために1分おきに更新する グラフを無効化した 今は使ってない 31

Slide 32

Slide 32 text

Elasticsearch + Kibana4 Elasticsearch 全文検索エンジン JSON APIでログ検索出来る ちゃんとスキーマ定義しておけば、数値の集計も可能 fluentdのpluginでログをElasticsearchに転送可能 Kibana4 Elasticsearchのフロントエンドツール ログの可視化/検索が出来る node 32

Slide 33

Slide 33 text

33

Slide 34

Slide 34 text

34

Slide 35

Slide 35 text

Kibana4の効用 検索結果から様々なグラフが簡単に作れる ようになった 複数のグラフをダッシュボードとして保存 できるので分析が捗った 本番サーバに入らなくてもアクセスログ検 索がお手軽に出来るようになった とはいえ、grep/sed/cut/wcする方が楽 に出来るものもあるがケースバイケース 35

Slide 36

Slide 36 text

Elasticsearch + Kibana4 気になる点 Elasticsearch若干重い データ量がでかい ログサーバの生ログはgzip圧縮して るのでそれほど気にならない 36

Slide 37

Slide 37 text

まとめ 推測するな。計測せよ 計測のための材料をそろえよう 計測を便利にするためのツールをそろ えよう Kibana4便利 37