JRuby 上で実行するための既存の Rails アプリの移動
最終更新日 2020年04月10日(金)
Table of Contents
JRuby は、JVM 上で実行されるように記述された Ruby の実装です。JRuby は、MRI Ruby と互換性があるように記述されています。これらの実装には、注意すべきいくつかの違いがあります。最も注目すべき違いの 1 つは、JVM にはグローバル VM ロックがないため、Ruby コードの複数のスレッドを並列に実行できる点です。MRI が C で記述され、ネイティブな C 拡張機能をサポートするのに対して、JRuby には、これらの拡張機能を実行するためのサポートがあります。これが、コードの非互換性のポイントになる場合があります。
この記事では、Heroku で動作する既存の Rails プロジェクトを JRuby 上で実行されるように変換する方法を示します。ここでは、一貫性のために Jruby 1.7.16
を使用します。サポートされているすべてのバージョンを確認するには、サポートされている Ruby バージョンの記事を参照してください。サポートされている最新バージョンを使用すると、最高のアプリケーションパフォーマンスが得られる可能性があります。
JRuby をローカルにインストールする
RVM を使用する場合は、最新の RVM バージョンを使用して JRuby をインストールできます。
$ rvm get latest
最新の RVM がインストールされたら、JRuby をローカルにインストールします。バージョン 1.7.16
をインストールする場合は、次のように実行します。
$ rvm install jruby 1.7.16
これで、JRuby をローカルで使用できるようになりました。
$ rvm use jruby-1.7.16
$ ruby -v
jruby 1.7.16 (1.9.3p203) 2012-10-22 ff1ebbe on Java HotSpot(TM) 64-Bit Server VM 1.6.0_33-b03-424-11M3720 [darwin-x86_64]
Gemfile で JRuby を指定する
JRuby がローカルにインストールされたら、Gemfile
に次の行を追加できます。
ruby '1.9.3', :engine => 'jruby', :engine_version => '1.7.16'
ここでは、アプリを Ruby 1.9.3 との互換モードで JRuby バージョン 1.7.0 で実行するよう Bundler に指示しています。bundle install
を実行するには、その前にアプリにいくつかの変更を加えておく必要があります。次に、それらを見ていきましょう。
サーバーを JRuby と互換性のあるサーバーに置き換える
多くの一般的な Ruby サーバーライブラリは C バインディングに依存しています。JRuby の GitHub ページには、いくつかの推奨されるサーバーがあります。使用可能なメモリを超えることなく、dyno 内で JRuby アプリケーションを実行できるサーバーが必要になります。純粋な Ruby Rack サーバーである Puma を使用できます。
gem 'puma'
また、Trinidad も適切に動作することが知られていますが、メモリフットプリントが少し大きい可能性があります。
gem 'trinidad'
Procfile を変更する
Procfile 内のコマンドを、選択した JRuby サーバーを使用してアプリを起動するように変更する必要があります。Puma Web サーバーの例を次に示します。
web: bundle exec rails server puma -p $PORT -e $RACK_ENV
JDBC データベースドライバー
Postgresql などの最も一般的なデータベース用の JDBC ドライバーはすでに JVM で使用可能です。ほとんどの JDBC ドライバーは非常に成熟しており、速度に関しては大幅に最適化されています。Gemfile から通常の pg
gem を削除する必要があります。
gem 'pg'
次に、それを activerecord-jdbcpostgresql-adapter
に置き換えます。
gem 'activerecord-jdbcpostgresql-adapter'
Gemfile への置き換えを行ったら、JRuby を使用していることを確認してください。
$ ruby -v
jruby 1.7.16
その後、$ bundle install
を実行します。失敗が表示された場合は、次のセクションを参照してください。
JRuby と互換性のない gem を置き換える
コミュニティ内の多くの gem は JRuby と互換性がありますが、互換性のないものを使用している必要があります。多くの gem 作成者は TravisCI での JRuby テストを有効にすることを選択するため、その最新のビルドを使用して互換性をチェックできます。プロジェクトが JRuby で動作するかどうかを示すレコードが存在しない場合は、常に Bundler でインストールしてみることができます。
$ bundle install
または、手動で次のようにします。
$ gem install puma
gem が正常にインストールされる場合でも、ライブラリに微妙なバグが存在する可能性があります。プロジェクトでテストを実行すると共に、互換性を確認するためにいくつかの手動のテストをローカルで実行することを常にお勧めします。
Twitter Bootstrap
JRuby で twitter-bootstrap-rails gem のさまざまなバージョンを使用した非互換性のレポートが発行されています。最新バージョンの gem へのアップグレードが必要になる場合があります。インストール手順は、twitter-bootstrap-rails の README で見つけることができます。
Heroku へのデプロイ
Rails プロジェクトが JRuby でローカルで動作するようになったら、コードを Git にコミットし、新しい Heroku アプリを起動してデプロイする必要があります
$ git add .
$ git commit -m "trying out JRuby on Heroku"
$ heroku create --remote jruby-heroku
これで、jruby-heroku
ブランチにプッシュすることによってデプロイできます。
$ git push jruby-heroku master
Counting objects: 692, done.
Delta compression using up to 4 threads.
Compressing objects: 100% (662/662), done.
Writing objects: 100% (692/692), 141.01 KiB, done.
Total 692 (delta 379), reused 0 (delta 0)
-----> Heroku receiving push
-----> Ruby/Rails app detected
-----> Using Ruby version: ruby-1.9.3-jruby-1.7.16
-----> Installing JVM: openjdk7-latest
-----> Installing dependencies using Bundler version 1.2.1
# ...
ブランチで変更を行っている場合は、my-branch:master
の規則を使用して Heroku にプッシュできます。たとえば、すべての変更を jruby-experiment
という名前のブランチで行った場合は、次を使用して Heroku にプッシュできます。
$ git push jruby-heroku jruby-experiment:master
何かエラーまたは警告が表示される場合は、メッセージを使用してデバッグし、問題のローカルでの再現を試みます。解決できない場合は、Stack Overflow でアプリケーション固有の質問を行うことができます。
トラブルシューティング
一般的なアドバイスについては、「Ruby バージョンの指定」のトラブルシューティングのセクションを参照してください。