SHOEISHA iD

※旧SEメンバーシップ会員の方は、同じ登録情報(メールアドレス&パスワード)でログインいただけます

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

特集記事

RabbitMQ 3.6の新機能「Lazy Queues」の概要と検証

  • X ポスト
  • このエントリーをはてなブックマークに追加

どうやって使うの?

 では実際にLazy Queuesを設定したキューを定義してやり、キューに対してメッセージを送る処理を記述してみます。

 まずはLazy Queuesを使わない、通常のキューを用いて以下の単純なPub-Subモデルのシステムを記述します。実装に当たり、Ruby(v2.2.2)とRuby版RabbitMQライブラリBunnyを用います。

system model
system model

通常のキュー

 まずはじめに、メッセージの送信処理を記述します。以下のコードはRabbitMQサーバ「mq-server」に対して、1KBのメッセージ送る処理になります。

require 'bunny'

c = Bunny.new(:host => 'mq-server', :user => 'tsuchinoko', :password => 'passwd')
c.start

ch = c.create_channel
q = ch.queue('basic-queue')

begin
  loop do
    q.publish('a' * 1024)
  end
rescue Exception => _
  ch.close
  c.close
end

 コードの中身を簡単に解説すると、3行目で設定したRabbitMQサーバの情報に基づいて、4行目でコネクションを確立させます。次に6行目でChannelと呼ばれるオブジェクトを生成します。ChannelはAMQPで規定されているメッセージブローカー内部での論理的接続で、一つのTCPコネクションで複数のChannelを定義させることができます。またキュー、エクスチェンジの設定・状態はChannelごとに独立します。なのでChannelに対する操作はスレッドセーフであり、安全に並列処理が行えます。

 そして7行目で「basic-queue」と名前付けしたキューを生成しています。10-12行目で、このキューに対してサイズ1KBのメッセージを送り続けます。

 続いて、受信処理を記述します。

require 'bunny'

c = Bunny.new(:host => 'mq-server', :user => 'tsuchinoko', :password => 'passwd')
c.start

ch = c.create_channel
q = ch.queue('default-queue')

begin
  q.subscribe(:block => true) do |delivery_info, properties, data|
    puts data
  end
rescue Exception => _
  ch.close
  c.close
end

 7行目まではメッセージ送信処理と同じです。メッセージの受信は10行目のsubscribeで行われます。サーバのキュー「basic-queue」にメッセージが存在すると、ブロック内部の処理が呼ばれます。ブロックで受け取っている3つのパラメータはそれぞれ以下のとおりです。

  • delivery_info:どういったアプリケーションから、どういった経路で送られたか、といったメッセージ転送処理に関する情報
  • properties:データタイプや永続化されているか、といったメッセージ自体のメタデータ情報
  • data:キューに格納されたメッセージの本体

Lazy Queuesを設定したキュー

 では、次にLazy Queuesを用いた送信処理を記述します。

 Lazy Queuesは、キューを宣言する際にパラメータ「x-queue-mode」に「lazy」を指定することでLazy Queuesを設定できます(デフォルトではLazy Queues非設定の「default」が指定されます)。

 以下は、Lazy Queuesを設定したキューを用いたメッセージの送信処理になります。

require 'bunny'

c = Bunny.new(:host => 'mq-server', :user => 'tsuchinoko', :password => 'passwd')
c.start

ch = c.create_channel
q = ch.queue('lazy-queue', :arguments => {'x-queue-mode' => 'lazy'})

begin
  loop do
    q.publish('a' * 1024)
  end
rescue Exception => _
  ch.close
  c.close
end

 先に示した、通常のキューの実装との差分は以下のとおりです。

--- basic_queues/sender.rb	2016-02-14 15:25:51.000000000 +0900
+++ lazy_queues/sender.rb	2016-02-14 23:35:36.000000000 +0900
@@ -6,7 +6,7 @@
 c.start
 
 ch = c.create_channel
-q = ch.queue('basic-queue')
+q = ch.queue('lazy-queue', :arguments => {'x-queue-mode' => 'lazy'})
 
 begin
   loop do

 RabbitMQでは、作成済みのキューに対してパラメータの変更を行うことはできないため、通常のキューとは別の名前「lazy-queue」を設定しています。すでに作成されているキューと同名のキューに対してLazy Queuesを設定する場合、deleteメソッドによって当該キューを削除してから、再定義してやる必要があります。

 同様に受信処理についても、Lazy Queuesを用いた場合とそうでない場合の差分を以下に示します。

--- basic_queues/receive.rb	2016-02-14 23:36:04.000000000 +0900
+++ lazy_queues/receive.rb	2016-02-14 23:36:28.000000000 +0900
@@ -6,7 +6,7 @@
 c.start
 
 ch = c.create_channel
-q = ch.queue('default-queue')
+q = ch.queue('lazy-queue', :arguments => {'x-queue-mode' => 'lazy'})
 
 begin
   q.subscribe(:block => true) do |delivery_info, properties, data|

 では実際にこれら2つの処理を動かして、RabbitMQサーバの振る舞いの違いを見てみましょう。

次のページ
動かしてみる

この記事は参考になりましたか?

  • X ポスト
  • このエントリーをはてなブックマークに追加
特集記事連載記事一覧

もっと読む

この記事の著者

大山 裕泰(株式会社DMM.comラボ)(オオヤマ ヒロヤス)

DMM.com ラボ所属ソフトウェアエンジニア。アリエル・ネットワーク株式会社、グリー株式会社を経て現在に至る。最近は主にインフラ基盤の構築、運用、機能開発を行う。共著書に「次世代ネットワーク制御技術 OpenFlow入門」がある。

※プロフィールは、執筆時点、または直近の記事の寄稿時点での内容です

この記事は参考になりましたか?

この記事をシェア

  • X ポスト
  • このエントリーをはてなブックマークに追加
CodeZine(コードジン)
https://codezine.jp/article/detail/9288 2016/03/18 14:00

おすすめ

アクセスランキング

アクセスランキング

イベント

CodeZine編集部では、現場で活躍するデベロッパーをスターにするためのカンファレンス「Developers Summit」や、エンジニアの生きざまをブーストするためのイベント「Developers Boost」など、さまざまなカンファレンスを企画・運営しています。

新規会員登録無料のご案内

  • ・全ての過去記事が閲覧できます
  • ・会員限定メルマガを受信できます

メールバックナンバー

アクセスランキング

アクセスランキング