
Nginx + Luaのよく知られた束は、多くの記事を含め、かなり長い間存在しています。 しかし、時は止まりません。 約1年前、RubyをNginxに統合するモジュールの最初のバージョンが登場しました。
ムルビー
統合には、本格的なRubyではなく、他のアプリケーションやデバイスなどに組み込まれるように設計されたサブセットが選択されました。 いくつかの制限がありますが、それ以外は完全なRubyです。 プロジェクトは
MRubyと呼ばれ
ます 。 現在、バージョン1.0.0、つまり 安定していると見なされます。
MRubyでは、実行時に他のファイルを添付することはできないため、プログラム全体を1つのファイルに含める必要があります。 同時に、プログラムをバイトコードに変換して実行することもできますが、これはパフォーマンスに良い影響を与えます。
なぜなら 他のファイルをロードする方法はありません。その場合、既存のgemはそれに適していません。 機能を拡張するために、独自の形式が使用されます。これは、一部の場所ではCコードとRubyの両方です。 これらのモジュールは、コンパイル時にライブラリ自体と一緒にアセンブルされ、その不可欠な部分です。 ファイルやネットワークなどを操作するためのさまざまなデータベースへのバインダーがあります。 完全なリストはサイトで入手できます。
また、このエンジンをNginxに統合できるモジュールがありますが、これは特に興味深いものでした。
ngx_mruby
だから
知ってください :
ngx_mruby 。 rubyスクリプトをnginxに接続するためのモジュール。 Luaバージョンと同様の機能を備えています。 要求処理のさまざまな段階で操作を実行できます。
モジュールは非常に簡単に構築され、サイトには詳細な手順があります。 アセンブリに煩わされたくない場合は、完成したパッケージをダウンロードできます。
http://mruby.ajieks.ru/st/nginx_1.4.4-1~mruby~precise_amd64.debこのアセンブリのMRubyには、次の追加モジュールが含まれています。
ご覧のとおり、仕事に必要なものはほぼすべてあります。 このモジュールがAPIで見つけられなかった唯一のものは、外部でリクエストを行う機能でした。 ほとんどの場合、拡張機能として実装し、nginx APIをバインドする必要があります。
著者はテスト付きの美しいグラフを表示していますが、環境の構成は見つかりませんでした。 したがって、私はそれを美しさに適用するだけです:

使ってみよう
そのため、サーバーは既にインストールされています。 すべてが機能し、静的が与えられます。 これにダイナミクスを少し追加します。
例として、追加のサーバーアプリケーションなしで、Markdownマークアップを解析し、HTMLでレンダリングするタスクを選択しました。 Rubyソースの行番号付けも同様です。
これを行うには、sinatraリポジトリのクローンを作成し、nginxを設定してタスクを解決します。
マークダウン
マークアップを処理するには、アセンブリに接続されたmruby-discountモジュールを使用します。 マークアップを操作するためのシンプルなクラスを提供します。 同じ名前のCライブラリに基づいているのは、パフォーマンスの問題が特に問題になるとは思わないからです。
まず、要求されたファイルをディスクから読み取り、処理してユーザーに提供するプログラムを作成します。
r = Nginx::Request.new m = Discount.new("/st/style.css", "README") filename = r.filename filename = File.join(filename, 'README.md') if filename.end_with?('/') markdown = File.exists?(filename) ? File.read(filename) : '' Nginx.rputs m.header Nginx.rputs m.md2html(markdown) Nginx.rputs m.footer
最初の行は、リクエストされたファイル、ヘッダー、URL、URIなどを含むすべての必要な情報を含むリクエストオブジェクトのインスタンスです。
次の行は、ディスカウントクラスのインスタンスを作成し、スタイルファイルとページタイトルを示します。
このコードは404エラーを処理しないため、ファイルがなくても、常に200の戻りコードがあります。
今、私たちはすべてを接続します
location ~ \.md$ { add_header Content-Type text/html; mruby_content_handler "/opt/app/parse_md.rb" cache; }
結果:
mruby.ajieks.ru/sinatramruby.ajieks.ru/sinatra/README.ru.mdRubyファイル
最初は、ナンバリングだけでなく、一度作成したコード
https://github.com/fuCtor/chalksを使用してコードに色を付けることも計画していました。 しかし、すべての適応が行われた後、彼の仕事に問題が生じました。 コードは機能しているように見えましたが、ある時点でセグメンテーションフォールトでクラッシュしました。 最初の疑いは割り当てられたメモリの不足でしたが、その消費を減らした後でも、問題は消えませんでした。 色付けに関連するコードを削除した後、すべてが機能しましたが、私が望んでいたほど美しくはありませんでした。
結果を変更する module CGI TABLE_FOR_ESCAPE_HTML__ = {"&"=>"&", '"'=>""", "<"=>"<", ">"=>">"} def self.escapeHTML(string) string.gsub(/[&\"<>]/) do |ch| TABLE_FOR_ESCAPE_HTML__[ch] end end end class String def ord self.bytes[0] end end class Chalk COMMENT_START_CHARS = { ruby: /
そして実際には、ファイルの読み取りと番号付けを実行するコード:
r = Nginx::Request.new Nginx.rputs '<html><link rel="stylesheet" href="/st/code.css" type="text/css" /><body>' begin ch = Chalk.new(r.filename) data = ch.to_html Nginx.rputs data rescue => e Nginx.rputs e.message end Nginx.rputs '</body></html>'
すべてを接続します。 なぜなら Chalkクラスは常に使用されているため、事前にロードします。
mruby_init '/opt/app/init.rb';
この行は、設定のサーバーセクションの前に追加されます。 次に、ハンドラーをすでに示しています。
location ~ \.rb$ { add_header Content-Type text/html; mruby_content_handler "/opt/app/parse_code.rb" cache; }
これで、結果を見ることができます:
mruby.ajieks.ru/sinatra/lib/sinatra/main.rbおわりに
したがって、別の言語を使用して、高度なクエリ処理、フィルタリング、キャッシングを実装できます。 このモジュールが戦闘条件で使用する準備ができているかどうかはわかりません。 テスト中、サーバー全体がフリーズしましたが、手の曲がりが発生する可能性があります。または、すべてが完全に開発されているわけではありません。 プロジェクトの開発をフォローします。
興味のある方は、上記のリンクを使用して、記事で指定されているパフォーマンススクリプトを実行できます。
サーバーは、最も単純なマシンであるUbuntu 12.04 x64のDigitalOceanにデプロイされます。 プロセス数2、接続1024。追加の設定は行われませんでした。 サーバーがハングした場合、10分ごとにnginxを再起動します。