プロトコル

AMQPとは?0-9-1と1.0の違い・ルーティングの仕組みと採用判断を実装者向けに解説

AMQP(Advanced Message Queuing Protocol)は、メッセージ指向ミドルウェア同士がメッセージをやり取りするための通信プロトコルです。名前の似た「0-9-1」と「1.0」がありますが、この二つは版違いではなく別のプロトコルで、そこを取り違えたままライブラリを選ぶと接続段階で行き詰まります。この記事では、exchangeとqueueによるルーティングの組み立て方、AMQP 1.0のリンクとクレジット方式、ポート5672で起きる版の交渉、MQTTやKafkaとの線引き、そして採用を見送るべき条件までを実装視点で整理しました。

まとめ|AMQPが効く境界と0-9-1・1.0の選び分け

先に結論を置きます。AMQPが効くのは、複数の言語・複数のチームで書かれた業務システムを、非同期で疎結合につなぐ場面です。送達保証とルーティング規則をプロトコル側が持つので、業務ロジックにリトライや宛先分岐を書き込まずに済みます。

版の選び分けは単純です。RabbitMQを自前で運用し、既存のクライアント資産とサンプルの量を取るなら0-9-1。Azure Service Busなどのマネージド基盤や、ブローカーをまたぐ相互接続を見込むなら1.0を選んでください。両者は名前が近いだけで、フレームもモデルも別物です。

新規に組むなら、2026年8月時点ではAMQP 1.0を第一候補に置いて構いません。RabbitMQ 4.0以降はプラグインなしで1.0を話せるため、かつて存在した「1.0を使うと構成が増える」という障壁が消えました。ただし言語によってはライブラリの成熟度に差が残るので、採用前に手元のスタックで疎通を確認してください。

そして最初に決めるべきは、ack(受信確認)とprefetchの方針です。ここを詰めずに走らせると、消費側が詰まったときにメッセージが無限に積み上がるか、逆に処理途中の落ちたメッセージが消えます。プロトコルの機能は揃っていても、どこで確認を返すかを決めるのは実装側の仕事になります。

AMQPとは何か|0-9-1と1.0が名前だけ同じ別プロトコルである理由

まず、この規格が何を引き受けていて何を引き受けていないのかを切り分けます。

メッセージ指向ミドルウェアの共通語としてのAMQPという規格の姿

AMQPが定義するのは、ワイヤ上のバイト列そのものです。どんなフレームをどの順で流し、どうやって送達を確認し、どこで接続を畳むか。ここまでを規格が決めているため、送信側と受信側が別ベンダーの実装でも会話が成立します。

裏返すと、AMQPは業務的な意味づけには関与しません。メッセージ本体は不透明なバイト列として運ばれ、JSONで書くのかProtocol Buffersで書くのかは利用側が決めます。TCP接続の確立そのものは下位層の担当で、そちらの層の整理はTCP/IPとは?4階層モデルとOSI参照モデルの違いを実装目線で解説で扱っています。

0-9-1と1.0の分岐点|JPモルガンからOASIS標準までの経緯

AMQPはJPモルガン・チェイスで生まれ、2008年以降は技術ベンダーとユーザー企業の20社超からなる中核グループで開発が進みました。2011年10月にOASISの専門委員会へ移管され、2012年10月30日にAMQP 1.0がOASIS Standardとして承認されています。その後ISO/IEC 19464:2014として国際標準になりました。

問題は、1.0が0-9-1の改訂版ではないことです。1.0は仕様が根本から書き直されており、0-9-1で中心に置かれていたexchangeやqueueの概念が仕様本体から外れています。0-9-1側は公式標準にならず、RabbitMQの実装が事実上の基準として広く使われてきました。

したがって、0-9-1のクライアントライブラリで1.0のブローカーに話しかけても通じません。ここを版番号の連続だと誤解したまま設計を進めると、疎通試験の段階で作り直しになります。

どちらの版を実装するか|クライアント資産と相互接続性の兼ね合い

判断材料は二つに絞れます。ひとつは手元の言語で使えるライブラリの厚み、もうひとつは接続先が固定かどうかです。

0-9-1はRabbitMQチームが保守するクライアントの数が多く、日本語の実装例も豊富に見つかります。社内のRabbitMQ一台に対してPythonやJavaから繋ぐだけなら、この厚みがそのまま開発速度になります。

1.0を選ぶ理由は相互接続性です。対応ブローカーの数は1.0のほうが多く、Azure Service BusのようなマネージドサービスやApache Qpid系のルーター、ブローカー間のシャベル転送まで同じプロトコルで通せます。将来ブローカーを移す可能性があるなら、最初から1.0で書いておくと移行コストが下がります。

AMQP 0-9-1のルーティングモデル|exchangeとqueueの分担

0-9-1の設計で特徴的なのは、送信側がキューを直接指定しない点です。

exchangeの4種類|direct・fanout・topic・headersの違い

publisherが送る先はexchangeで、そこからbinding(結びつけ規則)に従ってqueueへ複写されます。この間接層があるおかげで、宛先の増減がpublisherのコードに波及しません。exchangeの型は4種類です。

振り分けの基準 主な使いどころ
direct ルーティングキーの完全一致 処理種別ごとの振り分け
fanout キーを無視し全キューへ 全体通知・キャッシュ失効
topic キーのパターン一致 階層的なイベント配信
headers ヘッダ属性の一致 複数条件での振り分け

あらかじめ用意される名前もあります。amq.directamq.fanoutamq.topic、RabbitMQではamq.match(headers型)です。

バインディングとルーティングキーが決めるキューへの配送経路の作り方

topic型ではルーティングキーをドット区切りで階層化し、*で1語、#で0語以上をマッチさせます。order.jp.createdのようなキーに対し、order.*.createdorder.#で購読範囲を切り分ける形です。

ch.exchange_declare(exchange='orders', exchange_type='topic')
ch.queue_declare(queue='billing', durable=True)
ch.queue_bind(exchange='orders', queue='billing', routing_key='order.*.created')
ch.basic_qos(prefetch_count=20)

設計上の勘所は、ルーティングキーに業務語彙を持ち込みすぎないことです。「請求担当チームのキュー」のような組織由来の名前を入れると、組織変更のたびにpublisher側の文字列を書き換える羽目になります。キーはイベントの事実だけを表し、誰が受け取るかはbindingで表現してください。

チャネル多重化とprefetchとack|1接続で流量を制御する仕組み

0-9-1のクライアント操作は、すべてチャネル上で行われます。チャネルは1本のTCP接続を論理的に多重化する軽量な経路で、スレッドごとにチャネルを持たせる一方で接続自体は使い回すのが定石です。TCP接続の張り直しは高くつくため、接続は長寿命に保ちます。

受信側の流量はprefetch-countで抑える設計です。これは「ackを返していないメッセージを何件まで抱えるか」の上限で、RabbitMQはチャネル単位の指定のみに対応します。指定しないと1つの消費者が大量のメッセージを抱え込み、他の消費者が遊ぶ偏りが起きます。

ackには自動と明示の2種があります。自動ackはブローカーが送信した時点で削除するため、処理中にプロセスが落ちるとメッセージが消えます。業務データを運ぶなら明示ack(basic.ack)を選び、処理完了後に返してください。なお発行側の確認応答(publisher confirms)は0-9-1仕様そのものではなくRabbitMQの拡張で、送達保証を語るときは両端を分けて考える必要があります。

AMQP 1.0のリンクモデル|ブローカー非依存の転送が変えた前提

1.0はexchangeやqueueといったブローカー内部のモデルを仕様から切り離しました。定義するのは二者間の転送だけで、その先にキューがあるかルーターがあるかは問いません。

container・connection・session・linkの4層構造

1.0は、各層が入れ子になる階層構造です。container(プロセスやブローカーの単位)の間にconnectionを張り、その中にsessionを開き、さらにその中にlinkを張ります。実際のメッセージ転送はlink上で起きます。

linkには向きがあり、送る側がsender、受け取る側がreceiverです。この向きがクライアントとブローカーの役割に固定されていないため、同じプロトコルでクライアント間通信もブローカー間通信も表現できます。0-9-1が前提にしていた「中央にブローカーがいる」という形が、仕様の外へ出た格好です。

クレジット方式のフロー制御|受信側が流量の主導権を握る設計思想

1.0のフロー制御はクレジット(link credit)で動きます。receiverが「あと何件受け取れるか」をsenderへ通知し、senderはその範囲でしか送れません。0-9-1のprefetchと目的は同じですが、こちらは仕様の中核に据えられており、リンク単位で個別に調整できます。

これが効くのは、消費速度の異なる複数の購読を1接続に相乗りさせる構成です。RabbitMQの解説にあるとおり、消費側は取得元のキューごとに受け取り数を動的に変えて優先度をつけられます。重い集計処理のリンクだけクレジットを絞る、といった制御が接続を分けずに書けます。

settleとdisposition|accepted・rejectedが表す配送結果

1.0では、送達の確定を「settle(決着)」という語で扱う仕様です。senderが決着済みで送れば投げ放し、未決着で送ればreceiverからのdispositionフレームを待つ形になり、この使い分けで至多1回から厳密に1回までの信頼性を段階的に選択できます。RabbitMQのsender settle modeをmixedにすると、メッセージごとに確認の要否を切り替えられます。

配送結果(outcome)は4種類です。acceptedは処理成功、rejectedはメッセージが不正かキューの上限に触れた場合、releasedはどのキューにもルーティングできなかった場合、modifiedは消費側がアノテーションを変えて差し戻す場合を表します。0-9-1のackとnackより結果の粒度が細かく、再処理の分岐を組み立てやすいのが利点です。

MQTT・Kafka・HTTPとの違い|AMQPを選ぶ判断軸の置き方

「非同期にしたい」だけならAMQP以外の選択肢も並びます。差が出るのは保持のしかたと、経路上に何を置くかです。

方式 保持のモデル 向く場面
AMQP 消費で消えるキュー 業務系の非同期連携
MQTT 購読中の配信が中心 IoT・低帯域の端末
Kafka ログを一定期間保持 大量イベントの再処理
HTTP 保持しない同期呼出 即時の応答が要る処理

MQTTとの違い|IoT向けの軽さと業務系の信頼性という設計差

MQTTはヘッダを極限まで削り、細い回線と小さな端末で動くことを狙ったプロトコルです。トピック購読という単純な形に絞られており、AMQPのようなexchange型の選択やヘッダ条件での振り分けは持ちません。仕組みの詳細はMQTTとは?Pub/Subの仕組み・QoS・MQTT 5.0の実装からHTTPとの使い分けまで実装者向けに解説で扱っています。

選び分けの目安は端末側の制約です。マイコンやバッテリ駆動の機器から送るならMQTT、サーバ間で業務トランザクションに紐づくメッセージを運ぶならAMQPになります。さらに厳しい制約下ではUDPベースの選択肢もあり、そちらはCoAP(IoTプロトコル)とは?UDP上のRESTを支える仕組みとMQTTとの違いを実装視点で解説にまとめました。

Kafkaとの違い|ログ再読とキュー消費という異なる保持モデル

Kafkaはメッセージを消費しても消さず、保持期間の間はオフセットを戻して読み直せます。AMQPのキューは消費とackで消えるため、後から同じデータを別の用途で読むという使い方には向きません。この差は性能より前に、要件の形を決めます。

ブローカー製品としての比較はRabbitMQとKafkaの違いとは?設計思想・性能・使い分けの判断基準を実装視点で解説で詳しく扱っているので、製品選定の段階ではそちらを参照してください。本記事はプロトコル側の話に絞ります。

HTTPやgRPCで足りる場面|ブローカーを挟まない選択の条件

呼び出し元が結果を待つ処理に、ブローカーを挟む理由はありません。在庫照会や認証のように即答が要る経路は同期呼び出しのままにして、時間のかかる処理だけをキューへ逃がす切り分けが素直です。

逆にAMQPを挟む価値が出るのは、受け手が落ちていても送り手が止まらない設計にしたいときと、同じイベントを複数の後続処理へ配りたいときです。この二つが要件に無いなら、ブローカーの運用コストだけが残ります。

実装時に詰まる点|ポート5672とSASL・TLS・接続の張り方

設計が決まった後で足を取られるのは、たいてい接続まわりです。

プロトコルヘッダで決まる版|同じ5672番でも別物が流れる理由

RabbitMQは既定で5672番を待ち受け、そこでAMQP 1.0と0-9-1の両方を受け付けます。版が分かれるのはポートではありません。TCPまたはTLSを確立した後、AMQPフレームを送る前に、クライアントがプロトコルヘッダで「どちらを話すか」を宣言します。

この仕組みのため、ポート番号だけを見て版を判断できません。接続エラーの調査では、ファイアウォールやポートより先に、クライアントライブラリがどちらの版のヘッダを送っているかを確認してください。TLS利用時は5671番を使うのが慣例です。

あわせて、AMQP 1.0ではSASLが必須です。RabbitMQはSASLを実装しない1.0クライアントの接続を拒否します。0-9-1の感覚でユーザー名とパスワードだけ渡す実装を書くと、ここで弾かれます。

RabbitMQ 4系での運用|プラグイン不要になった1.0の扱い

以前のRabbitMQでAMQP 1.0を話すにはプラグインの導入が必要でしたが、公式ドキュメントが明記するとおり4.0以降はネイティブ対応となり、追加構成なしで1.0と0.9.1の双方を受け付けます。本体の最新安定版は4.3.4系(2026年7月時点)です。

この変化で、版の選択が構成上の負担ではなくなりました。3系から上げる場合は移行手順の確認が要りますが、新規構築なら4系を選び、クライアント側で版を決める形が扱いやすくなっています。ブローカーの構築手順そのものはMQTTブローカーとは?仕組み・主要ブローカー比較・構築手順を解説で扱う構成管理の考え方が参考になります。

マネージド側では、Azure Service BusがAMQP 1.0を主要な通信手段としています。WebSocket経由のAMQPも用意されており、こちらはTCP 443番で動くため、5672番を開けられないネットワークからでも通せます。

接続とチャネルの寿命設計|再接続とハートビートで詰まる落とし穴

本番で最も多い障害は、接続が切れたことに気づかないまま送り続ける状態です。AMQPは長寿命接続を前提とするので、ハートビート間隔を明示し、切断検知後に指数バックオフで張り直す処理をクライアント側に持たせてください。

チャネルの扱いにも癖があります。0-9-1ではチャネル上でエラーが起きるとそのチャネルが閉じられるため、再接続処理は接続とチャネルの両方を復旧させる必要があります。キューやexchangeの宣言(declare)は冪等なので、再接続のたびに宣言し直す実装で問題ありません。

もうひとつ、コンテナ環境ではロードバランサやNATのアイドルタイムアウトが接続を静かに切ります。ハートビート間隔はその値より短く設定してください。

AMQPを採用する条件と見送る場面|受託開発での持ち込み方の実際

ここまでの内容を、判断できる形に落とします。

採用が効くのは業務系の非同期連携と複数言語からの相互接続の現場

効くのは三つの条件が重なる場面です。処理を待たせたくない、送り先が複数ある、そして受け手が落ちても送り手を止めたくない。受発注の確定通知、帳票生成、外部システムへの連携などが典型になります。

言語が混在する現場でも効きます。Javaの基幹側とPythonのデータ処理をつなぐようなとき、プロトコルが標準であればブリッジを書かずに済み、合併後のシステム統合や旧システムへの連携口の追加でこの性質が生きます。

見送るべき場面|単一言語の小規模構成やマネージドサービスで足りる案件

単一言語・単一チームで、処理量も限られる構成なら、ブローカーを立てる価値は薄くなります。既にPostgreSQLを使っているなら、キュー機能を拡張で足すpgmqとは?PostgreSQLをメッセージキューにする拡張の使い方とSupabase Queues連携のような選択のほうが運用の面倒が少なく済みます。

クラウド上で完結する構成も同じです。SQS・Lambda・EventBridgeを用いた非同期処理の実践と運用方法で扱うようなマネージドの組み合わせなら、ブローカーの冗長化もバージョン更新も抱えずに済みます。AMQPを選ぶのは、標準プロトコルであること自体に価値がある場合に限ってください。

導入コストの実際|運用監視とDLQ設計にかかる工数と体制の見立て

実際にかかるのは、接続コードよりも運用設計の工数です。処理に失敗したメッセージをどこへ退避するか(デッドレターキュー)、何回まで再試行するか、滞留が何件を超えたら通知するか。この三つを決めずに本番へ出すと、障害時に手掛かりが残りません。

監視項目は、キュー内の未処理件数・ack待ちの件数・接続数とチャネル数・消費者の稼働数の4つを押さえておけば、障害の初期切り分けに足ります。

既存システムへメッセージング基盤を持ち込む場合、難所はプロトコルではなく既存側の改修範囲の見極めにあります。同期呼び出しをどこまで非同期へ倒すか、業務上の整合性をどこで担保するかは、現行の処理フローを読まないと決められません。API開発・システム連携では、こうした連携方式の選定から実装・運用までを一貫して請け負っています。方式の選択で迷っている段階でもご相談ください。

よくある質問

AMQP 0-9-1とAMQP 1.0はどちらを選べばよいですか?

RabbitMQ単体で完結し、既存のライブラリ資産やサンプルの多さを取るなら0-9-1、マネージドサービスやブローカーをまたぐ相互接続を見込むなら1.0です。RabbitMQ 4.0以降は追加プラグインなしで両方を受け付けるので、ブローカー側の構成負担では選べません。手元の言語でどちらのライブラリが成熟しているかを実際に試して決めてください。

AMQPとMQTTはどう使い分けますか?

端末側の制約で分けます。マイコンやバッテリ駆動の機器、細い回線の先から送るならMQTT、サーバ間で業務データを運ぶならAMQPです。AMQPはexchange型やヘッダ条件による振り分けを持ち、送達結果の粒度も細かいため、業務トランザクションに紐づくメッセージの扱いに向きます。

RabbitMQ以外にAMQPを話せるブローカーはありますか?

AMQP 1.0であれば、Azure Service BusやApache ActiveMQ、Apache Qpid系のブローカーとルーターが対応しています。クライアント側もApache Qpid Protonが多言語で提供され、Go・Python・Java・C++などから同じプロトコルで接続できます。0-9-1側はRabbitMQが事実上の基準で、対応実装の幅は1.0より狭いと考えてください。

exchangeを使わずキューへ直接送ることはできますか?

0-9-1では空文字名の既定exchangeを経由します。これはdirect型で、宣言済みのキューがキュー名と同じルーティングキーで自動的に結ばれるため、ルーティングキーにキュー名を指定すれば直接送っているように書けます。ただし宛先が増えるとpublisher側の改修が要るので、複数の受け手を見込むなら最初からexchangeを定義しておくほうが後が楽です。

メッセージの重複はAMQPだけで防げますか?

防ぎきれません。明示ackを使う構成では、処理は終わったがackを返す前に接続が切れた場合、ブローカーは未処理とみなして再配送します。受信側の処理を冪等に作るか、メッセージIDを記録して処理済みを判定する仕組みを業務側に用意してください。

関連記事

資料請求

RELATED POSTS 関連記事