(社内で共有した内容の転記です)
30d.jp に ngx_mruby を導入して、誰も手出しができないミドルウェアの置き換えとパフォーマンス向上を実現しました。
siege を用いたベンチマーク(siege -b -c 8 -r 50)でレスポンスタイムで 1割ちょっと、転送レートで 2割ちょっとの改善となりました。
Elap Time, Resp Time, Trans Rate, Throughput, Concurrent
**** nginx-1.6.2 + mruby ****
14.98, 0.26, 26.70, 4.54, 6.85
**** nginx-1.6.2 + perlbal ****
18.26, 0.29, 21.91, 3.72, 6.27
さらに今まで OS インストール時に密結合で構築していた perlbal の plugin が .rb として簡単に変更可能、かつテスト可能(これは重要)になったので、rails に到達する前に http のリクエストとレスポンスをプログラマブルに操作が可能となりました。便利。
今後、応用可能な例
夢が広がる〜。
userdata = Userdata.new("memcached_#{Process.pid}")
userdata.memcached = Memcached.new('<%= @memcached_server %>')
ここで nginx の worker ごとに memcached のコネクションを作ります。
userdata = Userdata.new("memcached_#{Process.pid}")
userdata.memcached.close if userdata.memcached
ここで worker の exit 時にコネクションを切るようにします(もしかしたら、worker process が回収するかもしれない)。
class DaysImageAuth
def initialize(r, c)
@r, @c = r, c
end
def allowed?
# 色々アクセスフィルタの処理を書く
# userdata.memcached.get でセッションデータを読み込んであれこれしたり
# 最終的にアクセスを通すなら true を返す
end
end
DaysImageAuth.new(Nginx::Request.new, Nginx::Connection.new).allowed?
(具体的な内容は書けないので参考にはならないけど、使い方のイメージとしてはこんな感じ)
このコードを mruby_set $allow 'your_mruby_code.rb'
というように指定すると nginx の $allow 変数に 'true' や 'false' が入るので、その値を見て 50x 返したり何かをしています。
ngx_mruby はイノベーティブ
RubyWorld Conference 2014 で RubyPrize 2014 を受賞しました。推薦していただいた皆さん、選考委員会の皆さん、応援していただいた皆さんありがとうございます。
今回の受賞に至る経緯や成果については記念講演のスライドを御覧ください。
講演はだいぶカミカミで個人的にはダメだったな〜という感触だったのですが、あちこちで大変良い話だったという感想を頂いたので、伝えたいメッセージは伝わったようで良かったです。引き続き、Ruby で楽しいプログラミングをするために色々やっていこうと思います。