rabbitmq-development について
メッセージ駆動型アプリケーションを開発する人向けの、RabbitMQ と AMQP の実践ガイドです。ルーティング、信頼性、性能、運用、セキュリティ、テストを扱います。
主な機能
- 01エクスチェンジとキューの設計
- 02信頼性と再試行のパターン
- 03接続とコンシューマーの調整
- 04セキュリティと監視の指針
- 05単体テストと統合テスト
活用シーン
- 01タスク分配キューの設計
- 02パブリッシュ・サブスクライブの構築
- 03リクエスト・レスポンス方式の実装
- 04ブローカー監視と障害対応の計画
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ mindrally/ skills --skill rabbitmq-developmentインストール後、Claude Code で/rabbitmq-developmentを入力して読み込まれたか確認します。
詳細
RabbitMQ 開発
RabbitMQ と AMQP(Advanced Message Queuing Protocol)開発のエキスパートとして、メッセージキューベースのアプリケーションを構築する際は、以下のベストプラクティスに従ってください。
基本原則
- RabbitMQ は、パブリッシャーからメッセージを受信し、コンシューマーにルーティングするメッセージブローカーです
- AMQP 0-9-1 は最も広く使用されているプロトコルです。バイナリ形式でデータを送信するアプリケーション層プロトコルです
- 信頼性、スケーラビリティ、フォールトトレランスを考慮して設計してください
- 実装に TODO、プレースホルダー、未完成の箇所を一切残さないでください
アーキテクチャのコンポーネント
エクスチェンジ
- ダイレクトエクスチェンジ:ルーティングキーの完全一致に基づいてルーティングします。ユニキャストルーティングに使用してください
- ファンアウトエクスチェンジ:ルーティングキーに関係なく、バインドされているすべてのキューにルーティングします。ブロードキャストに使用してください
- トピックエクスチェンジ:ワイルドカードパターンの照合に基づいてルーティングします。マルチキャストルーティングに使用してください
- ヘッダーエクスチェンジ:メッセージヘッダーの属性に基づいてルーティングします。複雑なルーティングロジックに使用してください
キュー
- キューは、メッセージが消費されるまで保持します
- 永続型(ブローカーの再起動後も保持)または一時型(メモリ内のみ)にできます
- 永続キューのメタデータはディスクに保存されます
- 一時キューのメタデータは、可能な場合はメモリに保存されます
バインディング
- ルーティングルールを使ってエクスチェンジとキューを接続します
- バインディングキーによって、どのメッセージがどのキューに届くかが決まります
- 複数のバインディングで、同じエクスチェンジを複数のキューに接続できます
キュー管理のベストプラクティス
キューサイズ
- キューサイズは小さく保ってください。大きなキューは RAM 使用量に大きな負荷をかけます
- RAM が不足すると、RabbitMQ はメッセージをディスクにフラッシュするため、パフォーマンスに影響します
- キューの深さを監視し、バックプレッシャーの仕組みを実装してください
- TTL(Time-To-Live)を使用して、古いメッセージを自動的に削除してください
キューの種類
クラシックキュー
- 従来の RabbitMQ キュー実装です
- ほとんどのユースケースに適しています
- すべての機能(レイジーキュー、優先度など)をサポートします
クォーラムキュー(推奨)
- RabbitMQ 3.8 で導入されました
- 高可用性とデータの安全性を実現する、レプリケーション対応のキュータイプです
x-queue-type: quorumを指定して宣言します- 耐久性とフォールトトレランスが必要なキューに使用してください
- ポリシーでは設定できません。クライアントによる宣言が必要です
パフォーマンスの最適化
- 耐久性が不要な場合は、スループットを最大化するために一時メッセージを使用してください
- 永続メッセージはすぐにディスクに書き込まれるため、スループットに影響します
- キューはシングルスレッドです。1 つのキューで最大約 50,000 件のメッセージを処理します
- マルチコアシステムでスループットを高めるには、複数のキューを使用してください
- 基盤となるノードのコア数と同じ数のキューを用意してください
接続とチャネルの管理
接続
- 各接続は約 100 KB の RAM を使用します(TLS の場合はさらに増えます)
- 数千の接続は、サーバーに大きな負荷をかける可能性があります
- アプリケーションに接続プールを実装してください
- 可能な限り接続を再利用してください
チャネル
- チャネルは、単一の TCP 接続を多重化する軽量な接続です
- パブリッシュとコンシュームはチャネル上で行われます
- メッセージごとではなく、スレッドまたは操作ごとにチャネルを作成してください
- 不要になったチャネルは閉じて、リソースを解放してください
プリフェッチとコンシューマーの設定
プリフェッチ(QoS)
- プリフェッチは、コンシューマーが一度に受信する未確認メッセージの数を定義します
- プリフェッチを設定することで、コンシューマーのスループットを最適化できます
- 低いプリフェッチ(1~10):公平に分配され、処理の遅いコンシューマーに適しています
- 高いプリフェッチ(100 以上):スループットは向上しますが、分配に偏りが生じるリスクがあります
- 中程度の値(50~100)から始め、メトリクスに基づいて調整してください
確認応答
- 自動確認応答:スループットは高くなりますが、障害発生時の保証は最も低くなります
- 手動確認応答:スループットは低くなりますが、信頼性は高くなります
- 経験則として、まず手動確認応答モードを検討してください
- サーバーのリソースを解放するため、処理後は速やかに確認応答を送信してください
メッセージ処理
メッセージのプロパティ
- 永続メッセージ(ブローカーの再起動後も保持される)には
delivery_mode=2を設定します - ペイロードの形式を示すには
content_typeを使用します - リクエスト/レスポンスのパターンには
correlation_idを含めます - 時間制限のあるメッセージには
expirationを設定します
パブリッシュのベストプラクティス
- 信頼性の高いパブリッシュには、パブリッシャー確認を使用します
- 返されたメッセージ(mandatory フラグ)を適切に処理します
- スループットを向上させるため、可能な場合はメッセージをバッチ処理します
- メッセージサイズを考慮します。大きなメッセージはパフォーマンスに影響します
エラー処理
デッドレター交換
- 失敗したメッセージを処理するため、DLX を設定します
- 次の場合、メッセージは DLX にルーティングされます。requeue=false で拒否された場合、TTL が期限切れになった場合、キューの長さが上限を超えた場合
- デッドレター化されたメッセージは、分析や再試行のために個別に処理します
再試行キューパターン
- 失敗したメッセージを同じキューに無期限に再キューイングしないでください
- 再試行ループを継続すると、自ら DoS 攻撃を引き起こすリスクがあります
- 遅延時間を段階的に増やす再試行キューを実装します
- 問題のあるメッセージを「timeout」キューに転送します
- 遅延時間の例:1s、5s、30s の後、デッドレターにします
サーキットブレーカー
- 下流の障害に備えてサーキットブレーカーパターンを実装します
- コンシューマーがメッセージを処理できないときに、キューが増え続けないようにします
- 再接続の試行には指数バックオフを使用します
高可用性
クラスタリング
- 高可用性を実現するため、RabbitMQ をクラスターでデプロイします
- レプリケーションされた永続キューにはクォーラムキューを使用します
- 適切なレプリカ数を設定します
ミラーリング(クラシックキュー)
- クラシックキューのミラーリングには
ha-modeポリシーを使用します - 新規デプロイでは、ミラーリングされたクラシックキューよりクォーラムキューを優先します
セキュリティ
認証
- 強力なパスワードを使用し、定期的に変更します
- エンタープライズ環境へのデプロイでは、LDAP または OAuth2 との連携を検討します
- 暗号化された接続を実現するため、TLS を有効にします
- アプリケーション/サービスごとに別々の認証情報を使用します
認可
- マルチテナントのシナリオでは、vhost による分離を実装します
- 必要最小限の権限(configure、write、read)を付与します
- 権限パターンを使用して、特定のリソースへのアクセスを制限します
モニタリングと可観測性
主要なメトリクス
- キューの深さ(準備完了メッセージ数、未確認メッセージ数)
- メッセージレート(パブリッシュ、配信、確認応答)
- 接続数とチャネル数
- メモリとディスクの使用量
- コンシューマーの使用率
管理プラグイン
- モニタリング UI を利用するため、管理プラグインを有効にします
- プログラムによるモニタリングには HTTP API を使用します
- メトリクスを Prometheus/Grafana にエクスポートします
アラート
- キューの深さがしきい値を超えたときにアラートを出します
- メモリとディスクのアラームを監視します
- コンシューマーの切断を追跡します
- メッセージレートの異常を監視します
テスト
単体テスト
- 分離してテストするため、RabbitMQ クライアントをモックします
- メッセージのシリアライズ/デシリアライズをテストします
- 交換とキューの宣言を検証します
統合テスト
- テストにはコンテナ化された RabbitMQ を使用します
- 障害シナリオ(接続の喪失、ブローカーの再起動)をテストします
- メッセージ確認応答の動作を検証します
- 実際の状況に即したメッセージレートで負荷テストを行います
一般的なパターン
ワークキュー(タスク分散)
- 負荷を分散するため、単一のキューに複数のコンシューマーを配置します
- 公平な分散を確保するため、プリフェッチを使用します
- タスクの完了後に確認応答を行います
パブリッシュ/サブスクライブ
- ブロードキャストにはファンアウト交換を使用します
- 各サブスクライバーは、交換にバインドされた専用のキューを持ちます
- サブスクリプションをフィルタリングする場合は、トピック交換を検討します
RPC(リクエスト/レスポンス)
- リクエストとレスポンスを対応付けるため、correlation_id を使用します
- クライアントごとに排他的な返信キューを作成します
- 保留中のリクエストにはタイムアウトを実装します
イベントソーシング
- イベントの配信には交換を使用します
- 複数のサービスがそれぞれ独立してイベントを消費できます
- パーティション内でイベントの順序を維持します
コメント
Markdown 対応