6.Springboot2.x RabbitMQのは、統合された電流制限、消費者、手動ACK確認を達成します

Springboot2.x RabbitMQのは、統合された電流制限、消費者、手動ACK確認を達成します

序文

私たちは限界にない場合は、我々はすべての上の突然の衝撃のメッセージの突然何千ものすべてが、サーバーを引き起こす可能性がある場合、消費者を開いたときに実際には、我々は、数千のメッセージでMQのものかもしれないの蓄積を予測しますダウン、またはビジネス深刻な脆弱性、私たちは、消費者が制限する必要があります。すべての私のspringbootバージョンのまず、springBootVersion = '2.2.1.RELEASE'。設定の違いの他のバージョンは大きくありません。

注:以前のバージョン2.0では、唯一MessageListenerContainer-SimpleMessageListenerContainer; 2.0後の第2容器--DirectMessageListenerContainer、次のように構成される。

    listener:
    #Container where the RabbitMQ consumer dispatches messages to an invoker thread.
      type: simple
      simple:
        acknowledge-mode: manual
        prefetch: 1
    #Container where the listener is invoked directly on the RabbitMQ consumer thread.
      type: direct
      direct:
        acknowledge-mode: manual
        prefetch: 1

SimpleMessageListenerContainer

デフォルトでは、リスナーはユーザーがキューからメッセージを受信し、単一のコンテナのユーザーを開始します。

テーブルの上に検査では、同時実行制御のプロパティの多くが表示されます。最も単純には、メッセージの同時処理にconcurrentConsumers、作成されたユーザーの数のみ(固定)です。

加えて、新しい属性maxConcurrentConsumersを追加し、コンテナは、動的ワークロードの並行処理に基づいて調整されます。continutiveactivetrigger、startConsumerMinInterval、continutiveidletrigger、stopConsumerMinInterval:4つの追加のプロパティと一緒にこの作品、。

次のようにデフォルトの設定では、増加する消費者の仕事のアルゴリズムは次のとおりです。

あなたはまだmaxConcurrentConsumersに達し、利用者の10回の連続サイクルを持っていない場合はアクティブで、開始から、ユーザは、少なくとも10秒であったが、その後、新しいユーザーを開始します。ユーザーがtxSize *に少なくとも一つのメッセージを受信した場合、ユーザがアクティブであると考えられます。

次のようにデフォルトの設定では、消費者のアルゴリズムを還元して動作します。

複数concurrentConsumersが実行され、そして消費者が10の連続するタイムアウト(アイドル状態)を検出し、少なくとも1人の消費者が60秒前に停止された場合、消費者は停止します。それはreceivetimeoutのとtxSize性質に依存しています。ユーザーが任意のメッセージtxSize *を受信しない場合、アイドル状態であると考えられます。したがって、デフォルトのタイムアウト(1秒)後txSizeが4で、40秒(アイドルタイムアウトに4対応が検出された)ユーザのアイドル時間が停止考えます。

DirectMessageListenerContainer

使用DirectMessageListenerContainerは、あなたがタスク実行を設定するには、ConnectionFactoryのを確認する必要があり、エグゼキュータは、ConnectionFactoryを使用してコンテナ内のすべてのリスナーで必要な同時実行をサポートするために十分なスレッドがあります。デフォルトの接続プールのサイズはわずか5です。

キューとconsumersPerQueueのベースの同時実行。単一チャネル、同時実行制御のウサギのクライアントライブラリを使用して、ユーザーごとに各キューは、デフォルトでは、5つのスレッドプールを使用しています。あなたは、所望の最大同時実行性を提供するためのTaskExecutorを設定することができます。

コントラスト

SimpleMessageListenerContainerは、次の機能を提供しますが、DirectMessageListenerContainerを提供していません。

  • txSize-使用SimpleMessageListenerContainerは、あなたはそれがメッセージの数が業務を配信制御および/またはACKの数を減らすように設定することができますが、これは繰り返し転送に失敗した後の数を増やすことになることがあります。( - 各メッセージの配信と、単一のトランザクションに包装txSize SimpleMessageListenerContainer、DirectMessageListenerContainerがmesagesPerAckで、ACKを減少させるために使用することができるが、トランザクションのために使用することができません)。

  • 伸縮自在のスペーサと消費者/いいえ自動開閉式のトリガー-DirectMessageListenerContainer maxconcurrentconsumer;しかし、それはあなたがプログラムでconsumersPerQueueの属性を変更することができ、それに応じてユーザーを調整します。

しかし、SimpleMessageListenerContainerと比較して、DirectMessageListenerContainerは、次のような利点があります。

  • より効率的に実行時にキューを追加したり、削除したり、使用SimpleMessageListenerContainer、全体のユーザスレッドを再起動します(すべてのユーザーがキャンセルして再作成する); DirectMessageListenerContainerため、影響を受けたユーザーがキャンセルされることはありません。
    コンテキストを避けることがRabbitMQのクライアントと消費者のスレッド間で切り替わります。
  • スレッドは、ユーザー間ではなく、各ユーザは、専用スレッドを有するSimpleMessageListenerContainerために共有されています。しかし、で構成された接続ファクトリについての重要な注意事項を参照してください「のスレッドと非同期コンシューマ。」

YML配置

spring:
  application:
    name: zoo-plus-rabbitmq
  rabbitmq:
    virtual-host: /
    host: localhost
    port: 5672
    username: guest
    password: guest
    listener:
      type: simple
      simple:
        acknowledge-mode: manual #采用手动应答
        prefetch: 1 #限制每次发送一条数据。

キューを作成します。

    /**
     * 测试队列
     */
    @Bean
    public Queue testQueue() {
        return QueueBuilder.nonDurable("test-queue").build();
    }

プロデューサー:

 
    /**
     * 发送五条数据,测试消费端必须ack才发送第二条,消费者限流
     */
    @GetMapping("ack")
    public Resp testAck() {
        for (int i = 0; i < 5; i++) {
            rabbitTemplate.convertAndSend("test-queue", "测试ack确认模式");
        }
        return Resp.success("ok", null);
    }

消費者:

    @RabbitListener(queues = {"test-queue"})
    public void testQueue(Message message, Channel channel) throws IOException {
        log.info("test-queue消费:" + new String(message.getBody()));
 
        /*
              listener:
                type: simple
                simple:
                  #采用手动应答
                  acknowledge-mode: manual
                  prefetch: 1 #限制每次发送一条数据。
         */
//        采用手动ack,一条条的消费
        channel.basicAck(message.getMessageProperties().getDeliveryTag(), false);
        
        /*
         * 还可以nack
         * 第三个参数是否重回队列
         */
//        channel.basicNack(message.getMessageProperties().getDeliveryTag(),false,true);
    }

上記の試験から、我々が設定されていない場合は、すべての突然の5つのメッセージのすべてがアップ混雑し、私たちはコンフィギュレーションを追加する場合、ない消費者側がACKだった場合、メッセージはunacked、次回は、あなたは、サービスが再びこのメッセージを送信します再起動します消費者側のACKまで。

ソースアドレスします。https://gitee.com/zoo-plus/springboot-learn/tree/2.x/springboot-middleware/rabbitmq

公開された476元の記事 ウォンの賞賛149 ビュー580 000 +

おすすめ

転載: blog.csdn.net/qq_36850813/article/details/104294766