シーン
開発には、時限タスクが必要になることがよくあります。モールの場合、クーポンのタイミングの有効期限、注文のタイミング終了、閉鎖注文に支払うことなく2時間の支払いなど、タイミングのあるタスクが特に多数あります。ただし、タイミングタスク自体に問題があります。一般的に言えば、タイムされたポーリングを通じてデータベースを照会して、実行するタスクがあるかどうかを判断します。つまり、何があっても、最初にデータベースを照会する必要があります。一部のタスクには、時間の正確性のために高い要件があり、1秒に1回照会する必要があります。システムが小さいかどうかは関係ありません。システム自体が大きく、多くのデータがある場合、これはそれほど現実的ではないため、他の方法が必要です。もちろん、Redis実装のタイミングキュー、優先順位キューに基づいてJDK遅延キュー、時間ラウンドなど、それらを実装する方法はたくさんあります。簡単な開発とメンテナンスの原則に基づいて、RabbitMQを使用して、RabbitMQ遅延キューを使用してタイミングタスクを実装します。 rabbitmqとは何か、またはスプリングブートがRabbitmqを統合する方法がわからない場合は、以前の記事Spring Boot Integrated Rabbitmqを確認できます
rabbitmq遅延キュー
Rabbitmq自体には遅延キューがなく、Rabbitmqのキューの特性を通じてのみ実装できます。 Rabbitmqが遅延キューを実装する場合、RabbitMQのDead-Letterスイッチ(Exchange)とメッセージサバイバルタイムTTL(Live to Live)を使用する必要があります
デッドレタースイッチ
次の条件が満たされている場合、メッセージはデッドレタースイッチを入力します。これはキューの代わりにスイッチであることを忘れないでください。スイッチは多くのキューに対応できます。
Dead Letter Switchは通常のスイッチですが、期限切れのメッセージを捨てるため、Dead Letter Switchと呼ばれます。死んだ文字スイッチが特定のスイッチであるという意味ではありません。
メッセージTTL(メッセージサバイバル時間)
メッセージのTTLは、メッセージのサバイバル時間です。 rabbitmqは、キューとメッセージのTTLを個別に設定できます。キュー設定は、キューに消費者に接続された保持時間がないことを意味し、個々のメッセージごとに個別の設定を作成することもできます。この時間の後、私たちはニュースが死んでいると考え、それは死の手紙と呼ばれています。キューが設定され、メッセージが設定されている場合、小さなものが撮影されます。したがって、メッセージが別のキューにルーティングされている場合、このメッセージの死の時間は異なる場合があります(異なるキュー設定)。ここでは、遅延タスクを実装するための鍵であるため、単一のメッセージのTTLについて説明します。
byte [] messagebodybytes = "hello、world!"。getBytes(); amqp.basicpropertiesプロパティ= new amqp.basicproperties(); properties.setexpiration( "60000"); Channel.BasicPublish( "my-exchange"、 "queue-key"、properties、messagebodybytes);
メッセージの有効期限フィールドまたはX-Message-TTLプロパティを設定することで時間を設定できます。どちらも同じ効果があります。有効期限フィールドが文字列パラメーターであるというだけなので、int-type文字列を記述する必要があります。上記のメッセージがキューにスローされると、60秒が渡された場合、消費されないと死にます。消費者は消費されません。このニュースの背後にあるニュースは「死んでいる」わけではなく、消費者によって消費されています。死んだ文字は削除されず、キューでリリースされ、キュー内のメッセージの数にカウントされます。
プロセスフローチャート
スイッチとキューを作成します
デッドレタースイッチを作成します
図に示すように、通常のスイッチを作成することです。簡単な区別のために、スイッチの名前は遅延です
自動有効期限メッセージキューを作成します
このキューの主な機能は、メッセージを定期的に期限切れにすることです。たとえば、2時間で注文を閉じる必要がある場合は、メッセージをこのキューに入れて、メッセージの有効期限を2時間に設定する必要があります
delay_queue1という名前の自動的に有効期限が切れたキューを作成します。もちろん、写真のパラメーターは、X-Message-TTLパラメーターを設定しないため、メッセージを自動的に期限切れにしません。キュー全体のメッセージが同じ場合、設定できます。柔軟性のために設定されていません。他の2つのパラメーターX-Dead-Letter-Exchangeは、メッセージの有効期限が切れた後にメッセージが入力されるスイッチを表します。ここでの構成は遅延、つまり死んだ文字スイッチです。 X-Dead-Letter-Routing-Keyは、メッセージが期限切れになった後、Dead Letter Switchのルーティングキーを構成することです。同じことが、メッセージのルーティングキーを送信することにも当てはまります。このキーによれば、メッセージは別のキューに配置されます。
メッセージ処理キューを作成します
このキューは、メッセージを本当に処理するキューであり、このキューに入力するすべてのメッセージが処理されます
メッセージキューの名前はdelay_queue2です
メッセージを切り替えるためにバインドされたメッセージキュー
[スイッチの詳細]ページを入力し、作成した2つのキュー( Queue1を遅らせてQueue2を遅らせる)をスイッチにバインドします。
自動有効期限のメッセージキューのルーティングキーは、遅延するように設定されています
バインド遅延キュー2
遅延queue2のキーを設定する必要があります。自動的に有効期限が切れたキューx-dead-letter-routing-keyパラメーターを作成して、メッセージが期限切れになると、メッセージをdelay_queue2 queueに自動的に配置できます。
バインドされた管理ページは、図に示されています。
もちろん、このバインディングは直感的な表現のためだけにコードを使用して実装することもできるため、この記事で使用される管理プラットフォームは操作に使用されます
メッセージを送信します
文字列msg = "hello word"; messageProperties messageProperties = new MessageProperties(); messageProperties.setexpiration( "6000"); messageProperties.setCorrelationId(uuid.randomuuid()。toString()。getBytes());メッセージメッセージ= new Message(msg.getBytes()、messageProperties); rabbittemplate.convertandsend( "delay"、 "delay"、message);
メインコードはです
messageProperties.setexpiration( "6000");
6秒後に有効期限を切るためにメッセージを設定します
注:メッセージは自動的に期限切れになるため、delay_queue1のリスニングを設定してはなりません。このキューのメッセージは受け入れられません。それ以外の場合、メッセージが消費されると、有効期限はありません。
メッセージを受信します
メッセージを聴くようにdelay_queue2を構成するだけです
パッケージwang.raye.rabbitmq.demo1; Import org.springframework.amqp.core.acknowledgemode; Import org.springframework.amqp.core.binding; Import org.springframework.amqp.core.binding; org.springframework.amqp.core.bindingBuilderをインポートします。 Import org.springframework.amqp.core.directexchange; Import org.springframework.amqp.core.message; Import org.springframework.amqp.core.queue; org.springframework.amqp.rabbit.connection.cachingconnectionfactoryをインポートします。 org.springframework.amqp.rabbit.connection.connectionFactoryをインポートします。 Import org.springframework.amqp.rabbit.core.channelawaremessageListener; Import org.springframework.amqp.rabbit.listener.simplemessageListenercontainer; Import org.springframework.beans.factory.annotation.autowired; org.springframework.context.annotation.beanをインポートします。 Import org.springframework.context.annotation.configuration; @configurationpublic class delayqueue { / **メッセージスイッチの名前* / public static final string exchange = "delay"; / **キューkey1*/ public static final string routingkey1 = "delay"; / **キューkey2*/ public static final string routingkey2 = "delay_key"; / ***構成リンク情報* @return*/ @bean public connectionfactory connectionfactory(){cachingConnectionFactory Factory = new CachingConnectionFactory( "120.76.237.8"、5672); ConnectionFactory.setUsername( "kberp"); ConnectionFactory.setPassWord( "kberp"); ConnectionFactory.setVirtualHost( "/"); connectionfactory.setpublisherconfirms(true); // connectionfactoryを返す必要があります。 } / ***メッセージスイッチの構成*消費者向けFanoutExchangeを構成:ルーティングキーヘッダーヘッダーセックスの概念なしに、すべてのバインドキューにメッセージを配信する:属性キーバリューを追加することによりDirectExchangeを一致させる:ルーティングキーTopicexchangeに従って指定されたキューに配布する:マルチキーマッチング* / @bean DirectChangeデフォルトエクスチャンゲ(真の誤ったexchange(){) } / ** *メッセージqueue 2 * configure * / @bean public queue queue(){return new queue( "delay_queue2"、true); //永続的な引用}/*** switch* with switch* configure for consumers*/@autowired public binding binding(){return bindingbuilder.bind(queue())。to(defaily.routingkey2); } / ***メッセージのリスナーを受け入れると、このリスナーはメッセージキュー1*消費者向けのメッセージを受け入れます* @return* / @autowired public simplemessagelistenercontainer messageContainer2(connectionFactoryFactory){simplemessageListenerconterer contaterer container.setqueues(queue()); container.setexposeListenerchannel(true); container.setMaxConcurrentConsumers(1); container.setConcurrentConsumers(1); container.setackNowledGemode(coundgemode.manual); //確認モードの設定手動確認container.setmessageListener(new ChannelAwaremessagElistener(){public void onmessage(message message、com.rabbitmq.client.channelチャンネル)スロー{byte [] body = message.getbody(); system.out.println channel.basicack(message.getMessageProperties()。getDeliverytag()、false);返品コンテナ。 }}メッセージのリスニング中に定期的に処理する必要があるタスクを処理するだけです。 rabbitmqはメッセージを送信できるため、注文を閉じたり、注文IDを送信するなど、タスク機能コードを送信できます。これにより、閉じられる必要がある注文を照会したり、MySQLの負担を増やす必要がありません。結局のところ、注文量が大きくなると、クエリ自体も非常に高価なものです。
要約します
RabbitMQに基づいてタイミングタスクの実装は、メッセージの有効期限を設定し、読み取られていないキューに入れて、有効期限が切れた後にメッセージが自動的に別のキューに転送され、このキューメッセージのリスナーがタイミングタスクの特定の操作を処理するように監視することです。
上記はこの記事のすべての内容です。みんなの学習に役立つことを願っています。誰もがwulin.comをもっとサポートすることを願っています。