Настроить Dead Letter Queue в Rabbit MQ
есть два микросервиса МС1 и МС2, которые общаются через Rabbit MQ. В МС2 в application.properties добавил настройки:
spring.cloud.function.definition=messageConsumer;messageProduce
spring.cloud.stream.bindings.messageConsumer-in-0.destination=work_company
spring.cloud.stream.bindings.messageProduce-out-0.destination=work_company
spring.cloud.stream.bindings.messageConsumer-in-0.group=work_company_group
spring.cloud.stream.bindings.messageProduce-out-0.group=work_company_group
spring.cloud.stream.rabbit.bindings.messageConsumer-in-0.consumer.auto-bind-dlq=true
Сама очередь DLQ создается, но когда из МС1 отправляется сообщение в МС2 даже если оба микросервиса включены выходит ошибка:
org.springframework.core.log.LogAccessor [ERROR] 08:50:45 - org.springframework.messaging.MessageHandlingException: error occurred in message handler [org.springframework.integration.amqp.outbound.AmqpOutboundEndpoint@40867d57], failedMessage=GenericMessage [payload=byte[2], headers={contentType=application/json, id=5c335ebf-80fc-2d09-9823-ff1779c2cc1d, timestamp=1704952233256}] at org.springframework.integration.support.utils.IntegrationUtils.wrapInHandlingExceptionIfNecessary(IntegrationUtils.java:191) at org.springframework.integration.handler.AbstractMessageHandler.doHandleMessage(AbstractMessageHandler.java:108) at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:73) at org.springframework.cloud.stream.binder.AbstractMessageChannelBinder$SendingHandler.handleMessageInternal(AbstractMessageChannelBinder.java:1196) at org.springframework.integration.handler.AbstractMessageHandler.doHandleMessage(AbstractMessageHandler.java:105) at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:73) at org.springframework.integration.dispatcher.AbstractDispatcher.tryOptimizedDispatch(AbstractDispatcher.java:132) at org.springframework.integration.dispatcher.UnicastingDispatcher.doDispatch(UnicastingDispatcher.java:133) at org.springframework.integration.dispatcher.UnicastingDispatcher.dispatch(UnicastingDispatcher.java:106) at org.springframework.integration.channel.AbstractSubscribableChannel.doSend(AbstractSubscribableChannel.java:72) at org.springframework.integration.channel.AbstractMessageChannel.sendInternal(AbstractMessageChannel.java:378) at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:332) at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:187) at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:166) at org.springframework.messaging.core.GenericMessagingTemplate.doSend(GenericMessagingTemplate.java:47) at org.springframework.messaging.core.AbstractMessageSendingTemplate.send(AbstractMessageSendingTemplate.java:109) at org.springframework.integration.router.AbstractMessageRouter.doSend(AbstractMessageRouter.java:228) at org.springframework.integration.router.AbstractMessageRouter.handleMessageInternal(AbstractMessageRouter.java:210) at org.springframework.integration.handler.AbstractMessageHandler.doHandleMessage(AbstractMessageHandler.java:105) at org.springframework.integration.handler.AbstractMessageHandler.handleMessage(AbstractMessageHandler.java:73) at org.springframework.integration.handler.AbstractMessageHandler.onNext(AbstractMessageHandler.java:131) at org.springframework.integration.handler.AbstractMessageHandler.onNext(AbstractMessageHandler.java:42) at org.springframework.integration.endpoint.ReactiveStreamsConsumer$SubscriberDecorator.hookOnNext(ReactiveStreamsConsumer.java:295) at org.springframework.integration.endpoint.ReactiveStreamsConsumer$SubscriberDecorator.hookOnNext(ReactiveStreamsConsumer.java:276) at reactor.core.publisher.BaseSubscriber.onNext(BaseSubscriber.java:160) at reactor.core.publisher.FluxRefCount$RefCountInner.onNext(FluxRefCount.java:238) at reactor.core.publisher.FluxPublish$PublishSubscriber.drain(FluxPublish.java:571) at reactor.core.publisher.FluxPublish$PublishSubscriber.onNext(FluxPublish.java:310) at reactor.core.publisher.FluxDoFinally$DoFinallySubscriber.onNext(FluxDoFinally.java:113) at reactor.core.publisher.SinkManyEmitterProcessor.drain(SinkManyEmitterProcessor.java:476) at reactor.core.publisher.SinkManyEmitterProcessor.tryEmitNext(SinkManyEmitterProcessor.java:273) at reactor.core.publisher.SinkManySerialized.tryEmitNext(SinkManySerialized.java:100) at org.springframework.integration.channel.FluxMessageChannel.tryEmitMessage(FluxMessageChannel.java:86) at org.springframework.integration.channel.FluxMessageChannel.doSend(FluxMessageChannel.java:75) at org.springframework.integration.channel.AbstractMessageChannel.sendInternal(AbstractMessageChannel.java:378) at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:332) at org.springframework.integration.channel.AbstractMessageChannel.send(AbstractMessageChannel.java:302) at org.springframework.integration.channel.FluxMessageChannel.sendReactiveMessage(FluxMessageChannel.java:162) at org.springframework.integration.channel.FluxMessageChannel.lambda$subscribeTo$5(FluxMessageChannel.java:145) at reactor.core.publisher.FluxHandleFuseable$HandleFuseableSubscriber.onNext(FluxHandleFuseable.java:179) at reactor.core.publisher.Operators$ScalarSubscription.request(Operators.java:2571) at reactor.core.publisher.FluxHandleFuseable$HandleFuseableSubscriber.request(FluxHandleFuseable.java:260) at reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber.request(FluxContextWrite.java:136) at reactor.core.publisher.FluxFlatMap$FlatMapInner.onSubscribe(FluxFlatMap.java:968) at reactor.core.publisher.FluxContextWrite$ContextWriteSubscriber.onSubscribe(FluxContextWrite.java:101) at reactor.core.publisher.FluxHandleFuseable$HandleFuseableSubscriber.onSubscribe(FluxHandleFuseable.java:164) at reactor.core.publisher.MonoJust.subscribe(MonoJust.java:55) at reactor.core.publisher.Mono.subscribe(Mono.java:4512) at reactor.core.publisher.FluxFlatMap$FlatMapMain.onNext(FluxFlatMap.java:430) at reactor.core.publisher.FluxPublishOn$PublishOnSubscriber.runAsync(FluxPublishOn.java:440) at reactor.core.publisher.FluxPublishOn$PublishOnSubscriber.run(FluxPublishOn.java:527) at reactor.core.scheduler.WorkerTask.call(WorkerTask.java:84) at reactor.core.scheduler.WorkerTask.call(WorkerTask.java:37) at java.base/java.util.concurrent.FutureTask.run(FutureTask.java:264) at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:304) at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) at java.base/java.lang.Thread.run(Thread.java:833) Caused by: org.springframework.amqp.AmqpIOException: java.io.IOException at org.springframework.amqp.rabbit.support.RabbitExceptionTranslator.convertRabbitAccessException(RabbitExceptionTranslator.java:70) at org.springframework.amqp.rabbit.connection.RabbitAccessor.convertRabbitAccessException(RabbitAccessor.java:118) at org.springframework.amqp.rabbit.core.RabbitTemplate.doExecute(RabbitTemplate.java:2252) at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:2198) at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:2178) at org.springframework.amqp.rabbit.core.RabbitAdmin.initialize(RabbitAdmin.java:695) at org.springframework.amqp.rabbit.core.RabbitAdmin.lambda$afterPropertiesSet$14(RabbitAdmin.java:621) at org.springframework.retry.support.RetryTemplate.doExecute(RetryTemplate.java:329) at org.springframework.retry.support.RetryTemplate.execute(RetryTemplate.java:209) at org.springframework.amqp.rabbit.core.RabbitAdmin.lambda$afterPropertiesSet$15(RabbitAdmin.java:620) at org.springframework.amqp.rabbit.connection.CompositeConnectionListener.lambda$onCreate$0(CompositeConnectionListener.java:38) at java.base/java.util.concurrent.CopyOnWriteArrayList.forEach(CopyOnWriteArrayList.java:807) at org.springframework.amqp.rabbit.connection.CompositeConnectionListener.onCreate(CompositeConnectionListener.java:38) at org.springframework.amqp.rabbit.connection.CachingConnectionFactory.createConnection(CachingConnectionFactory.java:717) at org.springframework.amqp.rabbit.connection.ConnectionFactoryUtils.createConnection(ConnectionFactoryUtils.java:254) at org.springframework.amqp.rabbit.core.RabbitTemplate.doExecute(RabbitTemplate.java:2225) at org.springframework.amqp.rabbit.core.RabbitTemplate.execute(RabbitTemplate.java:2198) at org.springframework.amqp.rabbit.core.RabbitTemplate.send(RabbitTemplate.java:1119) at org.springframework.integration.amqp.outbound.AmqpOutboundEndpoint.doRabbitSend(AmqpOutboundEndpoint.java:250) at org.springframework.integration.amqp.outbound.AmqpOutboundEndpoint.send(AmqpOutboundEndpoint.java:231) at org.springframework.integration.amqp.outbound.AmqpOutboundEndpoint.handleRequestMessage(AmqpOutboundEndpoint.java:180) at org.springframework.integration.handler.AbstractReplyProducingMessageHandler.handleMessageInternal(AbstractReplyProducingMessageHandler.java:145) at org.springframework.integration.handler.AbstractMessageHandler.doHandleMessage(AbstractMessageHandler.java:105) ... 56 more Caused by: java.io.IOException at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:140) at com.rabbitmq.client.impl.AMQChannel.wrap(AMQChannel.java:136) at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:158) at com.rabbitmq.client.impl.ChannelN.queueDeclare(ChannelN.java:989) at com.rabbitmq.client.impl.ChannelN.queueDeclare(ChannelN.java:47) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at java.base/jdk.internal.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:77) at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.base/java.lang.reflect.Method.invoke(Method.java:568) at org.springframework.amqp.rabbit.connection.CachingConnectionFactory$CachedChannelInvocationHandler.invoke(CachingConnectionFactory.java:1167) at jdk.proxy2/jdk.proxy2.$Proxy163.queueDeclare(Unknown Source) at org.springframework.amqp.rabbit.core.RabbitAdmin.declareQueues(RabbitAdmin.java:856) at org.springframework.amqp.rabbit.core.RabbitAdmin.lambda$initialize$16(RabbitAdmin.java:697) at org.springframework.amqp.rabbit.core.RabbitTemplate.invokeAction(RabbitTemplate.java:2285) at org.springframework.amqp.rabbit.core.RabbitTemplate.doExecute(RabbitTemplate.java:2246) ... 76 more Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - inequivalent arg 'x-dead-letter-exchange' for queue 'work_company.work_company_group' in vhost '/': received none but current is the value 'DLX' of type 'longstr', class-id=50, method-id=10) at com.rabbitmq.utility.ValueOrException.getValue(ValueOrException.java:66) at com.rabbitmq.utility.BlockingValueOrException.uninterruptibleGetValue(BlockingValueOrException.java:36) at com.rabbitmq.client.impl.AMQChannel$BlockingRpcContinuation.getReply(AMQChannel.java:552) at com.rabbitmq.client.impl.AMQChannel.privateRpc(AMQChannel.java:316) at com.rabbitmq.client.impl.AMQChannel.exnWrappingRpc(AMQChannel.java:152) ... 88 more Caused by: com.rabbitmq.client.ShutdownSignalException: channel error; protocol method: #method<channel.close>(reply-code=406, reply-text=PRECONDITION_FAILED - inequivalent arg 'x-dead-letter-exchange' for queue 'work_company.work_company_group' in vhost '/': received none but current is the value 'DLX' of type 'longstr', class-id=50, method-id=10) at com.rabbitmq.client.impl.ChannelN.asyncShutdown(ChannelN.java:528) at com.rabbitmq.client.impl.ChannelN.processAsync(ChannelN.java:349) at com.rabbitmq.client.impl.AMQChannel.handleCompleteInboundCommand(AMQChannel.java:193) at com.rabbitmq.client.impl.AMQChannel.handleFrame(AMQChannel.java:125) at com.rabbitmq.client.impl.AMQConnection.readFrame(AMQConnection.java:761) at com.rabbitmq.client.impl.AMQConnection.access$400(AMQConnection.java:48) at com.rabbitmq.client.impl.AMQConnection$MainLoop.run(AMQConnection.java:688) ... 1 more
Подскажите пожалуйста, почему возникает ошибка? Если настройку:
spring.cloud.stream.rabbit.bindings.messageConsumer-in-0.consumer.auto-bind-dlq=true
удалить все нормально. Но мне нужно использовать DLQ чтобы отслеживать доставку сообщение в МС2
