更新情報

みなさんご存知のように、Rails 5では「ActionCable」というリアルタイム通信用の技術が追加されました。この技術を使えば、ウェブページの閲覧者が画面の操作を行わなくても、受動的に新しい情報をリアルタイムで取得できるようになります。

ActionCableの活用例には次のようなものがあります。

・サイトのお知らせや警告をリアルタイムでポップアップ表示する
・シングルページアプリで、更新があればデータを取得する
・コンテンツストリーミング
・ライブチャット

現在、様々なところで簡易チャットなどの開発チュートリアルが公開されていますが、商品化した例はまだ少ないようです。そこで本コラムでは、商品化レベルでActionScriptの利点と欠点を考察したブログ(https://blog.ably.io/rails-5-actioncable-the-good-and-bad-parts-1b56c3b31404)の概要を紹介したいと思います。

■ActionCableの利点

利点については他のサイトでも多く語られていることですので、簡単に列挙するにとどめておきたいと思います。詳細は引用元のブログでご覧ください。

1: ActionCableへの接続や認証がシンプルである
2: WebSocketをアプリ内に設置でき、クッキーの共有も可能である
3: 各サブスクリプションごとにチャンネルオブジェクトを作成でき、シンプルである
4: 接続やサブスクリプションが自動リカバリされる
5: ActionCableは双方向なので、送信も受信もできる
6: メモリ上にKey-Valueストア(KVS)を構築することができる高性能なソフトウェア「Redis」を使っている
7: Railsと同じviewロジックが使えるため、フロントエンドの構築が簡単である

■ActionCableの欠点

ActionCableの欠点は以下の通りです。これらについても、詳細な考察を引用元のブログで読むことができます。

1: 切断中のメッセージが紛失する

サーバーで管理されている接続状態の情報が失われると、クライアントが切断されている間に公開されたメッセージが失われてしまう。しかしActionCableには切断中に起こった出来事をキャッチアップしたり再生する手段がない。ActionCableを使う限り、メッセージが紛失する可能性を容認しなければならない。この問題を解決するのはとても複雑で大変であり、それゆえにRails開発チームも対処できていない。

2: 単一障害点がある

ActionCableはRedisのPub/Subに支援されているが、Redisインスタンスがダウンしたら、ActionCableもダウンしてしまう。クラスタリングももちろん一つの手立てだが、今現在Redisはクラスタデータベースのサービスを提供していない。

3: 待ち時間がある

メッセージはデータセンターのRailsサーバーを介して送受信されるが、サーバーから物理的に遠い場所にいるユーザーは送受信の待ち時間が多くなる。ゲームやファイナンシャルサービスのプラットフォームを立ち上げた場合、この待ち時間が問題になる。

4: 突然のエラーで接続状態の情報が破損する

例えばチャットアプリで、チャンネルに接続してきたユーザーの情報をRedis Setに保存し、切断したユーザーの情報をそこから削除することで、誰がオンラインかを監視している仕組みがあるとする。しかしもしサーバーが突然切断されたら、現在接続中のユーザー情報が削除されることがなく、永遠に残ってしまう。この問題を解決するためには、接続状態を共有するクラスタが必要だが、実装するのは複雑で大変である。

5: ACK/NACKがない

ACK = ACKnowledgement(肯定応答)
NACK = Negative ACKnowledgement(否定応答)
クライアントからActionCableに送ったメッセージが届いたかどうかを返信する機能がないため、チャットで送信したメッセージが相手に届いているかどうかを確認することができない。

6: ブラウザ制限がある

WebSocketを使うため、モダンブラウザやオープンネットワークでしか動作しない。

7: メッセージの順序が保証されない

公開される各メッセージにはシリアルナンバーがないので、受信側は順番通りにメッセージを処理できない。

8: プラットフォーム相互運用性がない

ActionCableはJavaScriptとRubyの技術であるので、iOS、Android、Go、Python、など他のプラットフォームのためのクライアントライブラリがない。ブラウザ以外のプラットフォームをサポートするならば、自分でライブラリを作らなければならないが、実装は難しく、とても時間がかかる。

■ActionCableのパフォーマンス

メッセージを1000通送るのに100ミリ秒かかるなら、10000通送るには最大で10倍の1000ミリ秒で送れるべき。しかしActionCableではもっと時間がかかる心配がある。

ActionCableへ10000クライアントを接続してみた。最初の2500クライアントを接続するためには17.5秒かかったが、最後の2500クライアントを接続するためには約4倍の71秒かかってしまった。10000クライアントつないだ後、何もしなくても数秒おきにCPU使用率が100%に急上昇してしまった。

■まとめ

ActionCableでRailsは前進したし、APIでRailsの一部として提供できるのもいい動きであるが、パフォーマンスやデータ配信が保証されない問題がある。それらを解決するためには、別のリアルタイム技術を選択するか、すでにActionCableの問題点を解決したライブラリなどを使う必要がある。

以上が引用元ブログからの概要になります。いくつかの問題点にはすでに解決策(ライブラリなど)があるようです。これらの情報がみなさまの開発に役立てばうれしいです。