なぜApacheにmrubyを組み込もうと思ったか

なぜWebサーバソフトウェアであるApacheやNginx等にmrubyを組み込もうと思ったのかを整理しておきたいと思いました。

目的はWebサーバの開発支援

  • Webサーバの開発支援をしたい

という壮大な目的が以前からありました。

それがどういうことかは後述するとして、ここでいうWebサーバの開発とは、Webサーバの内部機能拡張を指しています。それを行うにはどうしたら良いかをまず簡単に説明したいと思います。(スクラッチでWebサーバを1から実装するのもよいですが、ここではスコープ外とします)

例えば、Apacheを例にあげると、Webサーバの内部機能拡張はモジュール単位で組み込むという方法が取られています。ApacheやNginxはWebサーバの最低限の機能をコアとして持ち、サーバ管理者が必要になった機能を定義されているモジュールの実装方法にのっとって実装し、それをコアに組み込みます。そして、その機能をコアがリクエストからレスポンスまでに複数用意されている各種フックのタイミング(URLとFILEパスを紐付けるタイミングやレスポンスを返してログを書き込むタイミング等細かく存在する)で呼び出します。これが、基本的なApacheとモジュールの連携の仕組みです。

つまり、Apacheの内部機能拡張のためには、Apacheモジュールを実装しなければなりません。基本的にC言語で実装します。

Apacheモジュールの実装は簡単ではない

しかし、Apacheのモジュールの実装も決して簡単ではありません。

なぜかというと、Apacheのモジュール開発に関する日本語のドキュメントが極端に少ないからです。Apache1.3系では、パンダ本と言われるApacheモジュールの本がありましたが、今は販売していません。さらにはApacheのバージョンも2系になってからは大きくモジュールの実装方法が変わりました。しかし、2系以降の実装方法をまとめた日本語ドキュメントは少なく、また、Googleで調べてもHello Worldレベルのモジュール実装方法の域を出ている情報はほとんど無いといっても過言ではありません。洋書でも、The Apache Module Bookぐらいしか無いと思います。

結局、Apacheモジュールを深く作っていこうとすると、Apacheのソースを読め、という話になってしまって、ApacheはコテコテのC言語で、かつ、Apacheのフックの仕様を元に暗黙のルールに従って書かれているため、初心者が簡単に理解することはできません。

その結果、日本ではApacheというソフトウェアは当たり前に使われている一方で、Apacheの機能拡張のためのApacheモジュール開発の情報は少なく、おそらく企業内での閉ざされたノウハウになっていたりとか、そもそも、開発のスキルが世界と比べて劣っているのではないかと思い始めていました。

もっと日本でWebサーバ開発を盛り上げていきたい、と常々思っていました。

Apacheの内部機能を簡単に拡張したい

これから、Webサービスが中心となっていく時代において、それらに耐えうるWebサーバソフトウェアの発展は必要不可欠になると、個人的には考えています。それを推し進めていくためにはどうしたらよいかと考えました。そして、Webサーバの開発支援をするには、

  • 簡単にWebサーバの機能を拡張できるようにすればいいんじゃないか

という考えに行き着いたわけです。

これまで、mod_perlやmod_ruby等、いくつかのモジュールでApacheの機能拡張を実現する方法が考えられてきました。しかし、それらはWebコンテンツとしてPerlやRubyをCGIで動かした時よりも早く動く事が目的であって、サーバ内部の機能拡張はあくまでおまけのような機能でした。おまけになってしまった原因は以下が挙げられます。

  • Apacheの内部処理を拡張するために使うにはスクリプト言語は遅い
  • Apacheの内部処理として使うにはリソース使いすぎ

Apacheモジュールで組み込んだ実装は、リクエストがあってからレスポンスを返すまでの複数のフックのポイントで、必ず呼び出されるのが基本的な動きです。そのため、静的ファイルやfavicon.ico、さらには404を返すような処理でさえ、Apacheモジュールの実装を一旦は通ります。その処理のタイミングで、perlやruby等のスクリプト言語が逐次呼び出される事を考えると、あまりに適切でないことが理解できると思います。

その結果、このアプローチはあまり普及しませんでした。

組み込み型の超軽量スクリプトの登場

そこで、Luaと呼ばれる組み込みスクリプト言語の登場です。

これは、C言語に組み込んで、任意の実装部分をLuaを使ってスクリプトで記述することが可能になります。さらに、超軽量のスクリプトで、JAVAと同じぐらいの実行速度で動作し、もちろんスクリプト言語としても最速の実行速度をほこります。

この言語の登場によって、

  • C言語でゴリゴリと速度重視で書く必要はないが、PerlやRubyで書くのは遅すぎる。しかし、スクリプト言語の保守性と開発効率を利用したい

というようなニーズに応える事ができるようになり、一気に人気が高まります。もちろん、このニーズは上述したApacheモジュールでも当てはまり、Apache2.4(厳密には2.3)ではExperimentではありますが、Apacheモジュールの実装をLuaスクリプトで書いてそれをApacheの内部機能として動作させるためのインターフェイスが開発されました。それが、mod_luaです。

しかし、mod_luaの個人的に考える問題点としては以下が挙げられます。

  • Luaの記述はあまりインフラエンジニアに慣れ親しまれていない(と思う)
  • プロトタイプベースであること(Rubyのようなオブジェクト指向で書ける方が開発支援の観点で流行るのでは)
  • Apacheの内部処理を弄る機能がまだまだ未完成
  • Apacheの内部処理においてフックできるポイントが少ない(自分でフック箇所を増やしたりしていた

などと思っており、少し前までは自分でLuaのライブラリを作って機能を拡張したりしていました

mrubyの登場、そしてApacheへ組み込みへ至る

そして、ついに4月20日にmrubyが登場しました。

これは、まつもとゆきひろ氏がLuaを意識して、Rubyの実装で組み込みスクリプトを実現できないかと考えて開発した言語です。これは、上記のように考えてきていた自分にとっては、まさにピッタリの言語だったわけです。というか、運が良すぎて興奮したのを覚えています。

つまり、Rubyの実装に慣れ親しんだWeb系エンジニアが、オブジェクト指向で記述されたmrubyスクリプトでApache内部の拡張機能を実装できれば、Apacheの機能拡張の敷居が下がり盛り上がるのではないか。それを、これまで必死こいてApacheのソースを見てきた自分が、ApacheモジュールのC言語のドキュメントを書くかわりに、外部のmrubyスクリプトとApacheの内部処理を連携するためのインターフェイスを実装してやれば、日本中のエンジニアがrubyでApacheの内部機能を実装する日が来るのではないかと。

さらには、mrubyの軽量さと高速な実行速度を利用すれば、Apacheの内部処理としてフックされても、そこまで問題にならないのではないか。それよりも、機能拡張をスクリプトで簡単に実装・変更できることの優位性が、天秤にかけた場合、勝るのではないかと思ったのです。

そうして、Apacheの内部機能拡張をmrubyで実装できるようにするために、Apacheへのmruby組み込みを決断し、何度かの改修を経て生まれたのがmod_mrubyなのです。バージョン0.0.1では、mod_luaとmod_mrubyのベンチマークではmod_luaの方が早かったのですが、いくつかの実装の見直しを経て、最新バージョンの0.2.1ではmod_mrubyの方が早い結果になっています。

これからもっと早く、そして、もっと簡単にRubyのスクリプトでApacheの内部機能を拡張できるように、修正していきたいと思っています。

「なぜApacheにmrubyを組み込もうと思ったか」への4件のフィードバック

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