AMQPによるメッセージング
こんにちは。GREEのプラットフォーム開発部でインフラ系の仕事をしているmdoi(@m_doi)と申します。よろしくお願いします。今回は、AMQPについて簡単に紹介したいと思います。
はじめに
GREEで稼働中のサーバは、日々サーバの異常ログ、自己監視結果、メール等々、大量のメッセージをやり取りしています。しかしながら、共通のメッセージングインフラが存在しないため、それぞれが独立に色々なメッセージ送信を行っています。
サーバ台数の増大に伴って、メッセージ配送の負荷が無視できないレベルになって来ると、それらのメッセージングシステムについて、個別に負荷対策を施すなど運用上様々な問題が課題が出てきます。また、メッセージの種類によっては、その配送の仕組がスケーラビリティに欠けるものとが存在し、規模の増大に対応できなくなる恐れもあります。そのため、こういうった用途に使えるスケーラブルなメッセージングの仕組みを検討しています。
今回、その一環としてAMQPについて調べていたので、簡単にまとめてみました。
AMQPって?
AMQPとは、メッセージングのためのミドルウェアの振る舞いや、プロトコルを定めたオープンな仕様です。
AMQPで定義されるメッセージングシステムは、次の要素で構成されています。
-
Exchange
- Exchange は、生成されたMessageを受け取る役割を持ちます。そのMessageはBindingに従って、適切なMessage Queueへ渡します。
-
Binding
- ExchangeとMessageQueueの対応付けを行います。
-
Message Queue
- Messageを蓄積し、Consumer Applicationnに引き渡す役割を持ちます。
Messageの大まかな流れは、次のようになります。
- Publisher Applicationによって生成されたMessageは、Exchangeに渡される。
- ExchangeはBindingに基づいて、Messageを適切なMessage Queueに引き渡す。
- Consumer Applicationによって、Message QueueからMessageが取り出される。
Exchange について
Exchangeは、設定された配送方法やbinding従って、Message Queueにメッセージを配送する役割を持ちます。
Exchangeで指定可能な配送方法には、主に以下のようなものがあります。
-
Direct
- Direct な Exchange は、Messageに付与されているrouting keyと、bindingに設定されているbinding key を見て、routing key = binding key となるような、Message Queue に Message を配送します。
-
Fanout
- Fanout なExchangeは、bindされているMessage Queueすべてに受け取ったメッセージの配送を行います。
-
Topic
- こちらもDirectと同じで、メッセージにrouting keyを指定して、そのkeyを元に配送するMessage Queueを選択します。但し、keyを階層で区切った形にして、部分一致で配送先を選択させることができます。(*.Bにマッチするkeyはすべて受け取る、などの設定が可能)
他にも、headerがありますが、ここでは割愛します。
この辺りのMessage配送の柔軟性がAMQPの特徴だと思います。この仕組みを活用すれば、比較的柔軟に様々なMessageを振り分けて扱うことが出来そうです。
仕様には、QueueやExchangeの存在期間、バイナリプロトコルフォーマット等々、他にも重要な情報がたくさんありますので、使うことを考えている場合は
http://www.amqp.org/confluence/display/AMQP/AMQP+Specification
にある仕様書を一通りは抑えておくべきだと思います。
AMQPの実装
AMQPの代表的な実装として、ActiveMQやRabbitMQ等があります。特にRabbitMQは、オープンソースでErlangで記述されており、個人的にErlangが好きだったので、コードを追いかけつつ、こちらを評価してみようと思っています。また、その辺りの話も、こういった場でフィードバックできればと思っています。
ということで、Exchangeの説明だけという、なんとも中途半端な感じではありますが、AMQPによるメッセージ配送のイメージは掴んでいただけたかと思います。AMQPやRabbitMQに関しては日本語の情報があまりないので、活用事例や評価の情報がありましたら、どしどし公開してほしいなーと思っています!