すべてのプロダクト
Search
ドキュメントセンター

ApsaraMQ for RabbitMQ:Spring 統合

最終更新日:Jul 04, 2026

ApsaraMQ for RabbitMQ は、Spring フレームワーク用の SDK を提供します。このトピックでは、Spring SDK を統合してメッセージを送受信する方法について説明します。

前提条件

デモプロジェクト

SpringBootDemo.zip をクリックして、デモプロジェクトをダウンロードします。

手順1:パラメーターの設定

application.properties または application.yml ファイルで、設定パラメーターを設定します。 次の例では application.properties ファイルを使用します。

# エンドポイント。ApsaraMQ for RabbitMQ コンソールの [インスタンス詳細] ページで取得します。
spring.rabbitmq.host=XXXXXX.amqp.aliyuncs.com
# ApsaraMQ for RabbitMQ への接続に使用されるポート。
spring.rabbitmq.port=5672
# インスタンスの静的ユーザー名。ApsaraMQ for RabbitMQ コンソールの [静的アカウント] ページでユーザー名を確認します。
spring.rabbitmq.username=******
# インスタンスの静的パスワード。ApsaraMQ for RabbitMQ コンソールの [静적アカウント] ページでパスワードを確認します。
spring.rabbitmq.password=******
# 仮想ホスト。論理的な分離を提供します。ApsaraMQ for RabbitMQ コンソールの [Vhosts] ページで仮想ホストを確認します。
spring.rabbitmq.virtual-host=test_vhost
# メッセージ確認 (Ack) モード。
# 1. none:コンシューマーがメッセージを受信した後、消費が成功したかどうかに関係なく、サーバーはメッセージが正常に処理されたと見なします。これは RabbitMQ の autoAck モードです。
# 2. auto:メッセージが正常に消費された後、クライアントは自動的に ack を送信します。メッセージの処理に失敗した場合、クライアントは nack を送信するか、例外をスローします。明示的に Channel.basicAck() を呼び出す必要はありません。
# 3. manual:手動で Ack を送信します。メッセージが正常に消費された後、明示的に Channel.basicAck() を呼び出す必要があります。
spring.rabbitmq.listener.simple.acknowledge-mode=manual

# キャッシュモードを CONNECTION に設定します。ApsaraMQ for RabbitMQ は分散アーキテクチャーを使用します。CONNECTION モードでは、クライアントはクラスター内の複数のサービスノードに、より均等に接続できます。この方法は、負荷ホットスポットを効果的に防止し、メッセージの送受信と消費の効率を向上させます。
spring.rabbitmq.cache.connection.mode=connection
# 必要に応じて値を調整します。
spring.rabbitmq.cache.connection.size=50
# 必要に応じて値を調整します。
spring.rabbitmq.cache.channel.size=1

# コンシューマーが一度に処理できる未確認 (Ack) メッセージの最大数 (QoS)。ApsaraMQ for RabbitMQ サーバーは min{prefetch, 100} を QoS 値として使用します。コンシューマーの処理能力が低い場合は、この値を小さくしてください。
spring.rabbitmq.listener.simple.prefetch=100
# RabbitMQ リスナーの最小同時コンシューマー数。必要に応じて値を調整します。
spring.rabbitmq.listener.simple.concurrency=10
# RabbitMQ リスナーの最大同時コンシューマー数。消費率が十分に高い場合、クライアントは max-concurrency で指定した数のコンシューマーを起動してメッセージを消費します。
spring.rabbitmq.listener.simple.max-concurrency=20

接続とチャネルのベストプラクティス

ApsaraMQ for RabbitMQ は、バックエンドで分散型のマルチノードアーキテクチャーを使用します。サーバー側での単一ノードのパフォーマンスボトルネックを回避するために、クライアント接続を設定する際には、以下のベストプラクティスに従ってください。

  • CONNECTION モードの使用:クライアントがサーバーへの複数の TCP 接続を確立するように設定します。CONNECTION モードでは、単一のクライアントがバックエンドの複数のサービスノードに接続を分散させ、クラスター内の複数のノードのリソースを利用します。クライアントあたりの接続数 (CONNECTION) は、クライアントのトラフィック量に基づいて調整し、数十個程度に設定することを推奨します。

  • 頻繁な接続の確立と切断の回避:頻繁に接続を作成したり切断したりしないでください。接続の確立と切断を頻繁に繰り返すことは、メッセージの送受信と消費の効率を低下させます。操作ごとに接続を作成するのではなく、永続的な接続を維持してください。

  • 接続ごとのチャネル数の制限:単一の接続で作成できるチャネルの数を 50 以下に設定します。単一の接続にチャネルが多すぎると、TCP トラフィックが急増する可能性があります。時折発生するパケットの並べ替えと相まって、Linux Netfilter Conntrack メカニズムがパケットを INVALID として分類し、クライアントが RST を送信して接続をリセットする原因となる場合があります。

次のパラメーターを使用して、接続モードと CONNECTION/CHANNEL 数を設定できます。

  • spring.rabbitmq.cache.connection.mode - CONNECTION モードにするには、connection に設定します。

  • spring.rabbitmq.cache.connection.size - 接続数。推奨: 数十。

  • spring.rabbitmq.cache.channel.size - 接続あたりのチャネル数。推奨: 50 以下。

必要に応じて、次のオプション設定を追加できます。

オプション設定

プロパティ

説明

spring.rabbitmq.addresses

クライアントが接続するサーバーアドレス。複数のアドレスはカンマ (,) で区切ります。

spring.rabbitmq.hostspring.rabbitmq.addresses の両方を設定した場合、spring.rabbitmq.addresses パラメーターが優先されます。

spring.rabbitmq.dynamic

AmqpAdmin Bean を作成するかどうかを指定します。デフォルト値は true です。

spring.rabbitmq.connection-timeout

接続タイムアウト。単位:ミリ秒。値 0 はタイムアウトなしを示します。

spring.rabbitmq.requested-heartbeat

ハートビートタイムアウト。単位:秒。デフォルト値は 60 です。

spring.rabbitmq.publisher-confirms

パブリッシャー確認メカニズムを有効にするかどうかを指定します。

spring.rabbitmq.publisher-returns

パブリッシャーリターンメカニズムを有効にするかどうかを指定します。

spring.rabbitmq.ssl.enabled

SSL 証明書認証を有効にするかどうかを指定します。

spring.rabbitmq.ssl.key-store

SSL 証明書を保持するキーストアへのパス。

spring.rabbitmq.ssl.key-store-password

キーストアにアクセスするためのパスワード。

spring.rabbitmq.ssl.trust-store

信頼する証明書を格納するトラストストアへのパス。

spring.rabbitmq.ssl.trust-store-password

トラストストアにアクセスするためのパスワード。

spring.rabbitmq.ssl.algorithm

SSL で使用されるアルゴリズム (TLSv1.2 など)。

spring.rabbitmq.ssl.validate-server-certificate

サーバー証明書の検証を有効にするかどうかを指定します。

spring.rabbitmq.ssl.verify-hostname

ホスト名の検証を有効にするかどうかを指定します。

spring.rabbitmq.cache.channel.size

キャッシュに保持するチャネルの数。

spring.rabbitmq.cache.channel.checkout-timeout

キャッシュサイズに達したときにキャッシュからチャネルを取得するためのタイムアウト。

単位:ミリ秒。値が 0 の場合は、常に新しいチャネルが作成されます。

spring.rabbitmq.cache.connection.size

キャッシュされた接続の数。このパラメーターは CONNECTION モードでのみ有効です。

spring.rabbitmq.cache.connection.mode

接続キャッシュモード。有効な値は次のとおりです。

  • CHANNEL:CHANNEL モードでは、クライアントは単一の TCP 接続を再利用し、その上にすべてのチャネルを多重化します。低トラフィックのシナリオに適しています。

  • CONNECTION:CONNECTION モードでは、クライアントはクラスター内の複数のサービスノードに分散された複数の TCP 接続を確立します。マルチノードのリソースを活用するため、本番環境での使用が推奨されます。クライアントごとの接続数は、数十個程度に設定する必要があります。

spring.rabbitmq.listener.type

リスナーコンテナーのタイプ。有効な値は次のとおりです。

  • simple

  • direct

デフォルト値は simple です。

spring.rabbitmq.listener.simple.auto-startup

アプリケーションの起動時にコンテナーを自動的に開始するかどうかを指定します。デフォルト値は true です。

spring.rabbitmq.listener.simple.acknowledge-mode

メッセージ確認モード。有効な値は次のとおりです。

  • none:コンシューマーがメッセージを受信した後、消費が成功したかどうかに関係なく、サーバーはメッセージが正常に処理されたと見なします。これは RabbitMQ の autoAck モードです。

  • manual:手動で Ack を送信します。メッセージが正常に消費された後、明示的に Basic.ack を呼び出す必要があります。

  • auto:メッセージが正常に消費された後、クライアントは自動的に ack を送信します。メッセージの処理に失敗した場合、クライアントは nack を送信するか、例外をスローします。明示的に Basic.ack を呼び出す必要はありません。

デフォルト値は auto です。

spring.rabbitmq.listener.simple.concurrency

コンシューマーの最小数。

spring.rabbitmq.listener.simple.max-concurrency

コンシューマーの最大数。

spring.rabbitmq.listener.simple.prefetch

コンシューマーが一度に処理できる未確認 (Ack) メッセージの最大数。これは、Basic.qos メソッドを呼び出して QoS 値を設定するのと同じです。トランザクションが使用される場合、この値はトランザクションサイズ以上である必要があります。

spring.rabbitmq.listener.simple.transaction-size

トランザクションで処理するメッセージの数。

spring.rabbitmq.listener.simple.default-requeue-rejected

拒否されたメッセージを再キューイングするかどうかを指定します。デフォルト値は true です。

spring.rabbitmq.listener.simple.missing-queues-fatal

宣言されたキューがブローカーで利用できない場合にリスナーが失敗するかどうか、または実行時に1つ以上のキューが削除された場合にコンテナーが停止するかどうかを指定します。デフォルト値は true です。

spring.rabbitmq.listener.simple.idle-event-interval

アイドルコンテナーイベントをパブリッシュする間隔。単位:ミリ秒。

spring.rabbitmq.template.mandatory

必須メッセージングを有効にするかどうかを指定します。デフォルト値は false です。

spring.rabbitmq.template.receive-timeout

receive() 操作のタイムアウト。

spring.rabbitmq.template.reply-timeout

sendAndReceive() 操作のタイムアウト。

手順2:SDKを使用したメッセージの送受信

メッセージの生成

RabbitMQService で、依存性注入を介して RabbitTemplate を取得し、その send メソッドを呼び出してメッセージを送信します。

import org.springframework.amqp.core.Message;
import org.springframework.amqp.core.MessageProperties;
import org.springframework.amqp.core.Queue;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;
import java.util.UUID;

@Service
public class RabbitMQService {
    
    @Autowired
    private RabbitTemplate rabbitTemplate;

    public void sendMessage(String exchange, String routingKey, String content) {
        // MessageId を設定します。
        String msgId = UUID.randomUUID().toString();
        MessageProperties messageProperties = new MessageProperties();
        messageProperties.setMessageId(msgId);
        // メッセージを作成します。
        Message message = new Message(content.getBytes(StandardCharsets.UTF_8), messageProperties);
        /*
         * send() メソッドを呼び出してメッセージを送信します。
         * exchange:エクスチェンジの名前。
         * routingKey:ルーティングキー。
         * message:メッセージの内容。
         * correlationData はパブリッシャー確認に使用されます。
         */
        rabbitTemplate.send(exchange, routingKey, message, null);
    }
}

メッセージの消費

@RabbitListener アノテーションを使用して、メッセージを消費します:

import com.rabbitmq.client.Channel;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.RabbitHandler;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.stereotype.Component;

import java.util.Arrays;

@Component
public class MessageListener {

     /**
     * メッセージを受信します。
     * @param message メッセージ。
     * @param channel チャネル。
     * @throws IOException
     * queues を作成したキューの名前に置き換えます。
     */
    @RabbitListener(queues = "myQueue")
    public void receiveFromMyQueue(Message message, Channel channel) throws IOException {
        // ここにメッセージ消費のビジネスロジックを記述します。
        ...
        // Ack の有効期間 (消費タイムアウト) 内に Ack を返す必要があります。そうしないと、確認が無効になり、メッセージが再配信されます。
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
    }
}

以下に、RabbitListener の一般的なオプション設定を示します。

オプション設定

プロパティ

説明

ackMode

カスタムメッセージ確認モードで、spring.rabbitmq.listener.simple.acknowledge-mode の設定を上書きします。

admin

AMQP リソース管理のための AmqpAdmin への参照。

autoStartup

アプリケーションの起動時にコンテナーを自動的に開始するかどうかを指定します。この設定は、spring.rabbitmq.listener.simple.auto-startup 設定を上書きします。

bindings

キューとエクスチェンジ間のバインディングの配列で、バインディング情報が含まれます。

concurrency

リスナーコンテナーの同時実行スレッド数を設定します。

errorHandler

リスナーメソッドによってスローされた例外のエラーハンドラーを設定します。

exclusive

キューの排他モードを有効にします。これは、コンシューマーがキューへの排他的アクセス権を持ち、他のコンシューマーがそのキューからメッセージを受信できなくなることを意味します。この機能は現在サポートされていません。

queues

このリスナーがリッスンするキューを宣言します。

queuesToDeclare

明示的に宣言するキューを指定します。

重要事項

クライアントがメッセージの消費に RabbitTemplatereceiveAndConvert メソッドを使用しているかどうかを確認します。

このメソッドは、キュー名やタイムアウト期間などのパラメーターを受け入れます。タイムアウトが指定されている場合、内部処理ロジックには、メッセージを消費する前にまず BasicCancel コマンドを送信してコンシューマーサブスクリプションをキャンセルし、次に Ack を送信してメッセージを確認するという問題があります。

しかし、ApsaraMQ for RabbitMQ が BasicCancel リクエストを受信すると、対応するコンシューマーを直ちにキャンセルし、未確認のメッセージをすべて再キューイングします。このため、クライアントから送信された後続の Ack は事実上無効となり、サーバーはこれを有効な確認応答として扱わずにこれらのメッセージを再配信することで、クライアント側で重複消費が発生します。

さらに、キューのメッセージスループットが高い場合、キャンセルと再キューイングの操作が頻繁に行われると、メッセージの蓄積につながり、消費の安定性にさらに影響を及ぼす可能性があります。