少し前に、IIJさんによってmrubyの拡張ライブラリが公開されました。個人的にも待ちに待った公開だったので、これを使ってmod_mrubyで試しに何かしてみようと思い、エントリ名みたいな事をやってみました。
やったこととしては、
- mod_mrubyをiij/mrubyの拡張ライブラリ版に対応
- mod_mrubyでトラフィックを監視して閾値を超えたらtweetする機能を実装
です。
mod_mrubyをiij/mrubyの拡張ライブラリ版に対応
以下のように、Githubからmod_mrubyをダウンロードしてmakeすれば、iij/mruby拡張ライブラリ版のmod_mrubyがビルドされます。
make extend
インストールは今までどおりです。
make install
iij/mrubyの拡張ライブラリを使う事によって、mrubyで以下のようなクラスやメソッドが使えるようになります。ざっくりとリストアップしておきます。
- 追加クラス
- Digest
- Env
- File
- IO
- Process
- Regex
- TCP Socket
- UNIX Socket
- Syslog
- 拡張クラス
- Array
- Kernel
- String
細かい内容はiij/mrubyのgithubを見て下さい。mod_mrubyで追加したクラスとかぶっている所もありますが、変に先行で追加せずに公開を待ってよかったです。これからは、こちらを使っていこうと思います。これらが今後、mrubyの拡張ライブラリのスタンダードになれば良いですね。
mod_mrubyでトラフィックを監視して閾値を超えたらtweetする機能を実装
ということで、早速iij/mrubyを使って上記のような機能を実装してみました。これは非常に簡単で、mrubyでのtweetのサンプルをほとんどIIJさんが作ってくれていたので、それをmod_mruby用に少し改良してみただけです。ソースはgistに上げているので御覧ください。メインの処理は大体以下のようになっています。
class Traffic
def initialize(rate)
@rate = rate
end
def kbcheck
sb = Apache::Scoreboard.new()
kbpersec = sb.total_kbyte / sb.uptime * 100
Apache.errlogger(4, "kbpersec: " + kbpersec.to_s)
if kbpersec > @rate
true
else
false
end
end
end
#
# mod_mruby_tweet phase
#
CONSUMER_KEY = ''
CONSUMER_SECRET = ''
ACCESS_TOKEN = ''
ACCESS_TOKEN_SECRET = ''
simple_oauth = SimpleOAuth.new(CONSUMER_KEY, CONSUMER_SECRET, ACCESS_TOKEN, ACCESS_TOKEN_SECRET)
r = Apache::Request.new()
r.content_type = "text/html"
# traffic kbyte / sec is 10000(10MB/sec)
threshold = 10000
t = Traffic.new(threshold)
if t.kbcheck
msg = sprintf("mod_mruby: Traffic exceeded %s kbyte/sec on %s", threshold, Time.now.to_s)
response = simple_oauth.post('http://twitter.com/statuses/update.json', {
:status => msg
})
if response.code.to_i == 200
Apache.errlogger(4, sprintf("tweet success: '%s'", msg))
else
Apache.errlogger(4, sprintf("tweet failed: '%s'", msg))
Apache.errlogger(4, response.body)
end
end
Apache::return(Apache::DECLINED)
上記のコード内に、Twitterのhttps://dev.twitter.com/ からCreate appをして、CONSUMER KEYやACCECC TOKENを発行して登録します。そして、 例の如く、このスクリプトをApacheのconf、例えばmod_mrubyの設定であるmrubyAccessCheckerMiddleあたりに登録しておけば、アクセス時にApache内部のaccess_checkerフェイズでこのmrubyスクリプトをフックします。
このスクリプト内にthresholdで指定したトラフィック、例えば上記のサンプルコードのように10000KB/secを超えていたら、Apacheが勝手にそれを検知してtweetします。ですので、このままの実装だと、大量にアクセスがあるとその都度tweetしまくりますので、注意が必要です。即座にスパム登録されるでしょう。
きちんと、超過が継続中の場合はtweetせずに、超えた時あるいは下回った時だけtweetするような実装をした方がよいと思います。tweetが成功したかどうかをApacheのエラーログに記録するようにしています。
テストで閾値を0にしてみてためしてみると、きちんと以下のようにtweetされました。
mod_mruby: Traffic exceeded 0 kbyte/sec on Sat Sep 22 17:32:59 2012
— MATSUMOTO, Ryosukeさん (@matsumotory) 9月 22, 2012
最後に
このように、Apacheモジュールで書こうとするとそれなりに大変なApacheの内部処理もmod_mrubyを使えば簡単にRubyで実装できちゃいます。また、mod_mrubyはかなり高速に動作しますので、性能劣化の心配も最小限に抑える事ができるでしょう。
IIJさんのおかげで、mod_mrubyを使ってApacheの内部をコントロールするための実装の幅が増えたと思われます。ありがとうございました!
「Apacheがトラフィックを監視して勝手にtweetしてみた(mod_mruby + iij/mruby)」への1件のフィードバック
コメントは受け付けていません。