mod_mrubyでApacheのリバースプロキシを実装してみた

動作チェックはしていませんので、あくまでネタとして読んで頂くのが良いと思います。さらに、Rubyのコーディングスキルが低すぎて、いっぱい書くと荒が見えすぎてしまうため、今回は少ないコードにしました。

mod_mrubyの売りとしては、ApacheをRubyスクリプトで「高速に」コントロールできる事ですが、「どういうことができるの?」というイメージが付きにくいのでサンプルを書いてみました。

リバースプロキシ

例えば、複数のバックエンドのサーバがあって、それらにとある条件下でリバースプロキシとして振り分ける場合の処理を書いてみました。だいたいこういう実装になるんじゃないかと思います。

今回は、バックエンドサーバリストからランダムでサーバを選択する場合の処理を実装しました。

require "Apache"

backends = [
    "http://192.168.0.101:8888/",
    "http://192.168.0.102:8888/",
    "http://192.168.0.103:8888/",
    "http://192.168.0.104:8888/",
]

# この辺に色々条件を入れたり、backends配列から取り出すルールを別途定義したりするとmod_mrubyのうまみがでる?

r = Apache::Request.new()

r.handler  = "proxy-server"
r.proxyreq = Apache::PROXYREQ_REVERSE
r.filename = "proxy:" + backends[rand(backends.length)] + r.uri

Apache::return(Apache::OK)

結構簡単に書けるような気がするのですが、どうでしょう。これを、mrubyTranslateNameMiddleくらいでフックさせてやれば、想定した動きをするんじゃないかと思います。

mrubyTranslateNameMiddle /path/to/proxy.rb

vhost_alias的な動作(おまけ)

mod_vhost_aliasの簡易版みたいな処理なら以下のようなコードでできます。ドキュメントルート以下にホスト名のディレクトリが多数ある場合を想定しています。

requeire "Apache"

r = Apache::Request.new()
s = Apache::Server.new()

r.filename = s.docroot + "/" + r.hostname + "/" + r.uri

Apache::return(Apache::OK)

簡単ですね。

あ、そうそう、この場合のセキュリティはどう担保するの?とか、mod_vhost_aliasとsuEXECと併用できないとか、mod_perlやmod_phpやmod_rubyはApache権限で動くからセキュリティ的に弱い、といった問題はmod_process_securityで解決していますので、動的コンテンツをコンテンツのuid、gidで動的に実行するモジュールはmod_process_securityのアーキテクチャの記事をご覧ください。

「mod_mrubyでApacheのリバースプロキシを実装してみた」への1件のフィードバック

コメントは受け付けていません。