電書部技術班、電子書籍配信サーバーに挑む

第2回ホストを選ぶ~Google App EngineからHerokuへ

Google App Serverで明らかになった問題

前回はGoogle App Server(GAE)をホストとして開発を進めた経緯を解説しました。今回は、GAEで生じた問題点、そして最終的にホストの変えることになった経緯を詳解します。

当初は理想的に思えたGAEですが、電子書籍の配信サーバーのホストとして使ってみると、いくつか問題があることが分かりました。

タイムアウト

最大の問題は、電書のダウンロード時にときおりタイムアウトすることです。電書サーバーのダウンロードは、特定のURLにある静的なファイルをアクセスするのではなく、一度電書サーバーがリクエストを受けて、その後以下の処理を行っています。

  1. ベースになる電書データを取得
  2. メールアドレスを埋め込み
  3. EPUBならばzip圧縮
  4. クライアントに電書データを送信

リクエストを受けてからのGAEの起動にも時間がかかります。本来なら一度起動すればプロセスがメモリに常駐して、その後のリクエストは高速に処理されます。しかしGAEは、一定時間アクセスされないプロセスは積極的に破棄してしまうので、電書配信のような(アクセスが連続することのない)サービスでは、毎回アプリが起動されることになり、オーバーヘッドが大きくなります。さらにメールアドレスを埋め込む処理などが重なるとタイムアウトしてしまうようです。

ダウンロード時にエラーが起きれば、ユーザは不安になります。しかし、GAEの起動時間は短縮できません。Webフレームワークを軽量化するにもSinatra以上の候補は見当たりません。JRubyのオーバーヘッドを回避するためにPythonへの書き換えも検討しましたが、現実的な時間では無理であるという結論に至りました。

ライブラリ

また、DataMapperでmany to manyの関連が正しく動作しないことがありました。こうしたケースで、DataMapperの問題なのか、JRubyの問題なのか、JRuby上のDataMapperの実装の問題なのか、原因究明が難しいのも問題でした。

ファイルが作れない

GAEではファイルを作ることはできません。自分でコーディングする場合は(例えばStringIOを使って)回避すればいいのですが、ライブラリがファイルを使っている場合には、ライブラリを解析してパッチを当てるなどの対応が必要になります。

RubyベースのWebアプリホスティングサービスHeroku

そこでGAE以外のサーバーへの移行を検討しました。クラウドでRuby言語が簡単に使えそうなところを探し、Herokuにたどり着きました。Herokuには、以下のような特徴があります。

rack

HerokuはAmazon EC2上に構築された、rackベースのアプリサーバのホスティングサービスです。rackはrubyによるwebアプリケーションのベースになるライブラリで、⁠フレームワークのフレームワーク」と呼ばれることもあります。Ruby on RailsやSinatraを含め、多くのWebフレームワークがrack対応です。

クラウド

Herokuは最小構成での利用は無料です。データベース(postgresql)の容量と性能に応じていくつかのコースが用意されています。またdynoとワーカ(後述⁠⁠、プラグインによっても課金されます。課金は秒単位で、例えばアクセスの多い日(例えば文学フリマ当日)の昼間だけ、一ヶ月使えば何百ドルにもなる構成にすることもできます。

プラグイン

Herokuはruby環境なのでgemが使えますが、それとは別にプラグインがサポートされています。プラグインを使うことで他のサービスとの連携が可能になります。プラグインには、cron、memcached、CouchDB、SSL、全文検索、Eメール(200通/日までは無料)などがあり、現在も増え続けています。

dynoとワーカ

Webアプリのインスタンスは最小構成時には一つですが、設定で自由に増やすことができます。2つにすれば、同時に2つのリクエストを処理できます。インスタンス一つをdynoと呼びます。dynoは2つ目から課金され、一時間当たり0.05ドルです。

また、Delayed_jobライブラリでバックグラウンド処理が可能です。バックグラウンドのジョブ一つごとに、ワーカが一つ必要になります。ワーカは最小構成時には0で、自由に増やすことができます。これも一時間当たり0.05ドルです。長時間の処理でレスポンスが30秒以内に返せないようなときに利用します。

複数バージョンのrubyサポート

Herokuは複数のrubyバージョンをサポートしています。これを「スタック」と呼び、スタックを切り替えることで異なるrubyを利用できます。バージョン1.8.6、1.8.7、1.9.1、1.9.2が利用可能で、切り替えにはherokuのコマンドを使います。

スタックを1.8.7対応に切り換える
heroku stack:migrate bamboo-ree-1.8.7

herokuコマンド

Herokuの設定等を行うherokuコマンドは、gemでインストールします。プラグインのインストール、dynoとワーカ数の設定、アプリの作成・リネーム・削除、ログの表示、コンソールの起動などの多くのサブコマンドがあります。heroku helpで確認してみてください。

Herokuへの移行

GAE版からの移行では、以下のような作業を行いました。

不要なファイルの削除

GAEでは必須だったWEB-INFディレクトリは不要なので削除しました。

gitの準備

HerokuへWebアプリをデプロイするには、gitを使ってpushする必要があります。クライアントにはgitツールとsshの環境が必須です。Windowsの場合、msysgitが利用できます。sshのエラーが出る場合には、sshのconfigファイルを作り、以下のように指定しておくと上手に進むことがあります。

~/.ssh/config での設定
Host heroku.com
Hostname heroku.com
Port 22
IdentitiesOnly yes
IdentityFile ~/.ssh/id_rsa 
TCPKeepAlive yes
User ユーザ名

メール送信の書き換え

メール送信はシステムに依存するので書き換えが必要でした。herokuでのメール送信は、GMailを使う方法と、SendGridプラグインを使う方法があります。GMailは追加のライブラリなどは不要です。この手軽さはいいですね。ただし一日200通しか送れません。SendGridプラグインは、Freeバージョンで200通/日、Proバージョンで20,000通/月、Premiumバージョンなら100,000通まで送信できます。

SengGridのよいところはどのバージョンでも同じ設定が使えて、負荷に応じてプラグインを切り換えられる点です。ProとPremiumは課金されますが、クラウドらしく必要な期間だけ送信を増やすという使い方ができます。プラグインの入れ替えは、以下のherokuコマンドを実行するだけです。

SendGridプラグインのインストール
heroku addons:add sendgrid:free

Herokuに移行した結果

GAEで起きていたダウンロード時のタイムアウトは解消され、文学フリマではこのシステムを使うことになりました。次回はその文学フリマバージョンの詳細を解説します。

おすすめ記事

記事・ニュース一覧