spring amqp と Rabbit MQ を使用してバックオフ ポリシーで再試行を実装する良い方法を探していますが、要件はリスナーをブロックしないことです (したがって、他のメッセージを自由に処理できます)。ここで同様の質問/回答が見られますが、「バックオフ」の解決策は含まれていません。
RabbitMQ & Spring amqp は、コンシューマーをブロックせずに再試行します
私が持っている質問は次のとおりです。
デフォルトの spring-retry 実装は、再試行中にスレッドをブロックしますか? github での実装は、そうであることを示しています。
上記の仮定が当てはまる場合、これを行う唯一の方法は、再試行用に個別のキュー (DLQ?) を実装し、各メッセージに TTL を設定することです (バックオフ間隔でスレッドをブロックしたくないと仮定します)。
上記のアプローチ (DLQ または別のキュー) を使用する場合、再試行ごとに別のキューが必要ではないでしょうか? 再試行に 1 つのキューのみを使用する場合、同じキューには、最小再試行間隔から最大再試行間隔までの範囲の TTL を持つメッセージが含まれます。キューの先頭のメッセージに最大 TTL がある場合、その後ろのメッセージは最小 TTL がある場合でもピックアップされます。これは、Rabbit MQ TTL のドキュメント(こちらの警告を参照) によるものです。
ノンブロッキング バックオフ リトライ メカニズムを実装する別の方法はありますか?
@garyrussel のトラブルシューティングに役立つ構成情報を追加します。
キュー構成:
<rabbit:queue name="regular_requests_queue"/>
<rabbit:queue name="retry_requests_queue">
<rabbit:queue-arguments>
<entry key="x-dead-letter-exchange" value="regular_exchange" />
</rabbit:queue-arguments>
</rabbit:queue>
<rabbit:direct-exchange name="regular_exchange">
<rabbit:bindings>
<rabbit:binding queue="regular_requests_queue" key="regular-request-key"/>
</rabbit:bindings>
</rabbit:direct-exchange>
<rabbit:direct-exchange name="retry_exchange">
<rabbit:bindings>
<rabbit:binding queue="retry_requests_queue"/>
</rabbit:bindings>
</rabbit:direct-exchange>
<bean id="retryRecoverer" class="com.testretry.RetryRecoverer">
<constructor-arg ref="retryTemplate"/>
<constructor-arg value="retry_exchange"/>
</bean>
<rabbit:template id="templateWithOneRetry" connection-factory="connectionFactory" exchange="regular_exchange" retry-template="retryTemplate"/>
<rabbit:template id="retryTemplate" connection-factory="connectionFactory" exchange="retry_exchange"/>
<bean id="retryTemplate" class="org.springframework.retry.support.RetryTemplate">
<property name="retryPolicy">
<bean class="org.springframework.retry.policy.SimpleRetryPolicy">
<property name="maxAttempts" value="1"/>
</bean>
</property>
</bean>