ども、mod_mruby ngx_mruby Advent Calendar 2014 19 日目担当、初心者枠の cloudpackかっぱ (@inokara) です。

はじめに

以前「Nginx で構築したリバースプロキシを ngx_mruby で細かい制御をする試み(1)」に ngx_mruby を利用して、コネクション数を監視してアクセス制限を試してみましたが、今回は Nginx 内部で保持しているコネクション数をはじめ取得可能な値を InfluxDB に放り込んで可視化してみたいと思います。

既に @matsumotory さんが mod_mruby と GrowthForecast で同様のことを実践されていらっしますのでご一読ください。

当初は同じように Growthforecast を利用しようと思いましたが、InfluxDB と Tasseo の組み合わせが面白そうなので mrbgems 作成の勉強を兼ねて InfluxDB を利用してみました。

動作イメージ

ngx_mruby で Nginx への接続数等の内部情報を取得して InfluxDB と Tasseo で可視化してみる: 構成図

  1. client マシンでは ab を実行して nginx マシンに ab を使ってアクセスします
  2. 定期的に(テストでは 1 秒に一回)情報取得の URL(127.0.0.1/nginx-status)にアクセスします
  3. 情報取得用の URL にアクセスすると下記の Nginx 内部情報を ngx_mruby を介して取得して InfluxDB にポストします
  4. InfluxDB に書き込んだ時系列データは Tasseo と呼ばれる可視化ツールでリアルタイムに確認します

以下は ngx_mruby を介して取得する Nginx の内部情報です。

  • connections_active
  • connections_reading
  • connections_writing
  • connections_waiting
  • connection_requests

これらの値は ngx_mruby の Nginx::Var クラスで取得することが出来ます。

尚、上記の管理用端末以外は Docker コンテナで作りました。各々の Dockerfile はそのうちにアップしたいと思います。

メモ

準備

こちら「Install · matsumoto-r/ngx_mruby Wiki」を参考に ngx_mruby をまずはセットアップしましょう。次に ngx_mruby をセットアップする際に利用した build.sh に以下を追加します。

  conf.gem :git => 'https://github.com/iij/mruby-io.git'
  conf.gem :git => 'https://github.com/iij/mruby-socket.git'
  conf.gem :git => 'https://github.com/iij/mruby-pack.git'
  conf.gem :git => 'https://github.com/suzukaze/mruby-msgpack.git'
  conf.gem :git => 'https://github.com/mattn/mruby-http.git'
  conf.gem :git => 'https://github.com/y-ken/mruby-simplehttp-socket.git'
  conf.gem :git => 'https://github.com/matsumoto-r/mruby-simplehttp.git'
  conf.gem :git => 'https://github.com/matsumoto-r/mruby-httprequest.git'
  conf.gem :git => 'https://github.com/y-ken/fluent-logger-mruby.git'
  conf.gem :git => 'https://github.com/luisbebop/mruby-polarssl.git'
  conf.gem :git => 'https://github.com/iij/mruby-mtest.git'
  conf.gem :git => 'https://github.com/iij/mruby-digest.git'
  conf.gem :git => 'https://github.com/mattn/mruby-uv.git'
  conf.gem :git => 'https://github.com/iij/mruby-aws-s3.git'
  conf.gem :git => 'https://github.com/mattn/mruby-json.git'
  conf.gem :git => 'https://github.com/mattn/mruby-base64.git'
  conf.gem :git => 'https://github.com/inokappa/mruby-influxdb-client.git'

全てが必要ではありませんが、HTTP を処理する為の mruby-httpmruby-simplehttp は必須ですので忘れずに追加しましょう。あと、先日作った mruby-influxdb-client も追加しましょう。

追加した上で以下のように再ビルドして再インストールしましょう。

sh build.sh
make install

尚、InfluxDB のセットアップ等は割愛させて頂きますm(__)m

Nginx の内部情報を ngx_mruby から取得して InfluxDB に突っ込む hook スクリプト

先日作った mruby-influxdb-client はココで生きてきます(笑)

v = Nginx::Var.new

conn_act  = v.connections_active
conn_read = v.connections_reading
conn_wri  = v.connections_writing
conn_wait = v.connections_waiting
conn_req  = v.connection_requests

config = {
  :url  => "http://127.0.0.1:8086",
  :db   => "foo",
  :ua   => "mruby-influxdb-client",
  :user => "root",
  :pass => "root",
}

i = Influxdb::Client.new(config)
points = [ conn_act.to_f, conn_read.to_f, conn_wri.to_f, conn_wait.to_f, conn_req.to_f ]
data = [{
  :name => "Test_Metrics",
  :columns => ["conn_act", "conn_read", "conn_wri", "conn_wait", "conn_req" ],
  :points => [
  points
  ]
}]
Nginx.echo "#{points}"
Nginx.echo "#{data}"
i.post(data)
Nginx.return Nginx::HTTP_OK

特に難しいことはなく Nginx::Var を初期化して、各値はそれぞれメソッドとして取得します。あとはそれぞの値を InfluxDB に放り込んでいきます。

hook スクリプトを呼び出す Nginx の設定

以下のように nginx.conf に設定します。

        location /nginx-status {
            mruby_content_handler /usr/local/nginx/hook/nginx-status.rb;
        }

mruby_content_handler に hook スクリプトのパスを追加するだけです。
簡単ですね。

アクセスしてみる

以下は client 側(下半分)から ab を断続的に実行しつつ、nginx 側(上半分)で情報取得用の URL に断続的にアクセスしている図です。
ngx_mruby で Nginx への接続数等の内部情報を取得して InfluxDB と Tasseo で可視化してみる: 動作確認(1)

下半分はあまり変化はありませんが、http://172.17.0.30 に対して断続的に ab を実行しています(watch コマンドを利用しています)

この状態で InfluxDB でメトリクスを確認すると以下のように各値が登録されていることがわかります。(途中で値の登録を止めてしまった為に途中が抜けてしまっていますが見逃してください…)
ngx_mruby で Nginx への接続数等の内部情報を取得して InfluxDB と Tasseo で可視化してみる: 動作確認(2)

Tasseo でリアルタイムで値の変化を見る

さらに Tasseo を設定して InfluxDB のデータベースを見てみると以下のようにリアルタイムに値が変化していくのも見ることが出来ます。(Tasseo については改めて書きます)
ngx_mruby で Nginx への接続数等の内部情報を取得して InfluxDB と Tasseo で可視化してみる: 動作確認(3)

Tasseo 自体は自動的にリロードが行われて InfluxDB から値を取得するので上記のようにリアルタイムに値が変化して見えるようです。なんかカッコイイですね。

ということで…

あまり ngx_mruby のテクニックは書くことが出来ずお恥ずかしい限りですが、munin 等のツールを利用しなくても ngx_mruby を使うだけで Nginx の内部情報を取得することが出来るという試みでした。また、メトリクスの収集とデータストアへの登録も mruby と mrbgems を利用することでリソース消費も抑えることが出来るのではないかと思います。。

元記事はこちらです。
ngx_mruby で Nginx への接続数等の内部情報を取得して InfluxDB と Tasseo で可視化してみる