RabbitMQを導入すると… “依存しないカンケイ”でもっと幸せになれる!?

近年話題になっているメッセージキューイングミドルウェア、RabbitMQ。今回は、その特徴や利点はどのようなところにあるのか、簡単なサンプルプログラムを作成しながら解説していきます。

メッセージキューイングという設計方法

さて、エンジニアのみなさんは次のような文章を読んだとき、どのような設計方法を思い浮かべるでしょうか?

あなたが作成しているのは、有名なネットオークションサイトです。
利用者は非常に多く、ひとつの商品に対しての入札者は平均で十名程度、多い時で数十名程度になるときがあります。そのサイトで実装される予定のいくつかの機能のうち、あなたは「出品者が商品の説明文を変更した場合、入札者全員に変更内容をメールで通知する」という機能の担当となりました。

この機能を実装するにあたり、考えられる「一番簡単に実装できそうな設計方法」とは、以下の図のようなものだと思います。

image1 (1)

このような設計方法を採った場合、全入札者に対してメールが送信されるまで処理が完了しないため、出品者がボタンを押してからかなり長い間待たされてしまうことになります。加えて、もし何かの障害が発生して「商品の説明文を変更する処理」もしくは「メールを送信する処理」のどちらかが実行出来なくなってしまった場合、もう一方の処理にも影響が出てしまうことになります。

どうしてこのような問題が生じてしまうのでしょうか?それは、「商品の説明文を変更する処理」と「メールを送信する処理」の2つが密結合となってしまっているからです。機能間の連携は疎結合であることが望ましく、何かしらの方法を使ってこの2つの依存関係を無くす必要があります。

そうした実装を行うにあたって、非常に便利なのが「メッセージキューイング」という仕組みです。メッセージキューイングとは、2つ以上の処理を連携させる際に、1番目の処理でデータをどこかの領域に保管(キューイング)しておき、2番目以降はそのキューイングされたデータを使用して処理を行う方式のことです。1番目の処理は、2番目以降の処理の応答を待つことなく次の処理を行うことが出来ます。

メッセージキューイングの仕組みを使い、先ほどの設計方法を再検討すると以下の図のようなものになります。

image2 (1)

このような設計方法を採れば、出品者がボタンを押してから待たされる時間はかなり短縮出来ることが分かります。また、2つの処理のうちどちらかが実行出来なくなってしまったとしても、もう一方の処理には影響が出なくなっていることが分かるかと思います。

RabbitMQの登場

上述のようなメッセージキューイングの仕組みを導入して作られているミドルウェアはいくつもありますが、その中でも有名なものとしてRabbitMQ(ラビットエムキュー)が挙げられます。RabbitMQはErlang(アーラン)言語で記述されており、2015年12月現在、EMC(イーエムシー)とVMware(ブイエムウェア)、GE(ジーイー)の出資で設立されたPivotal(ピボタル)社が開発・サポートを行っています。

それでは、実際にRabbitMQを使用して、簡単なアプリケーションを作成してみましょう!

環境構築

まずは、RabbitMQをインストールしましょう。
今回は以下の条件で環境構築を行っています。

Ubuntu 14.04
Ruby 2.2.3

※ 以降の作業はRabbitMQ公式サイトのインストール手順 ( http://www.rabbitmq.com/install-debian.html ) を参考にしています ※

ターミナルより、以下のコマンドを実行してください。

コマンド実行が完了したら、Webブラウザで以下URLにアクセスしてください。
http://127.0.0.1:15672/
RabbitMQ管理画面が表示されれば、インストールは成功です!

image3

メッセージの送受信

※ 以降の作業はRabbitMQ公式サイトのチュートリアル ( https://www.rabbitmq.com/tutorials/tutorial-one-ruby.html ) を参考にしています ※

それでは、1番目の処理がメッセージを送信し、2番目の処理がそのメッセージを受信してコンソール上に表示する、という2つのプログラムを作成してみます。まずは、Rubygems(ルビージェムズ)を使用してBunny(バニー)をインストールします。

次に、1番目の処理である「メッセージを送信する」Rubyコードを書いてみます。

send.rb

Bunny.new ~ ch.queue(“hello”) の処理で、local環境のRabbitMQサーバにある「hello」という名のキューに接続しています。そしてpublishの処理で「Hello World!」というメッセージを登録しています。
次のコマンドを叩き、実際にプログラムを実行してみましょう。

最後に、2番目の処理である「メッセージを受信してコンソール上に表示する」Rubyコードを書いてみます。

receive.rb

さきほどのプログラムと同様、local環境のRabbitMQサーバにある「hello」という名のキューに接続した後、subscribeの処理でメッセージを受信し、その中身をputsによって表示させています。

次のコマンドを叩き、実際にプログラムを実行してみましょう。

上手くいきました!

さいごに

機能間の依存をどうやって少なくしようかと悩んでいるエンジニアにとって、RabbitMQはきっと助けになると思います。RabbitMQを使って、疎結合かつ障害に強い設計を実現してみてください。

ライター:ぞの

ライター画像

Webアプリケーションエンジニアとして様々な現場に参画し、多種多様な言語を習得。エンジニアとしての強みは汎用性の高さと、メンバーとコミュニケーションを取り合いながら円滑に案件を進められること。趣味は音楽と将棋。Ruby愛好家。


 

最新情報はFacebook/Twitterをフォロー!

 


関連する記事

facebook

案件情報や最新記事をお届けします。
ぜひチェックしてみてください。