Spring 启动 rabbitmq 死队列不会在异常时停止流
Spring boot rabbitmq dead queue not stopping flow on exception
我正在学习 spring boot (version 2.2.5.RELEASE) with RabbitMQ 基于在线 resources:
我遇到的问题是,当我故意抛出异常时,它应该只重试 6 次,之后消息应该被移动到死队列,但事实并非如此,因为它不断重试而不停止.
请在下面找到我的 application.yml:
server:
servlet:
contextPath: /test
spring:
rabbitmq:
username: guest
password: guest
listener:
simple:
retry:
enabled: true
initial-interval: 3s
max-attempts: 6
max-interval: 10s
multiplier: 2
请在下面找到rabbitMQ配置class:
@Configuration
public class RabbitMQConfig {
@Bean
TopicExchange deadLetterExchange() {
return new TopicExchange("deadLetterExchange");
}
@Bean
TopicExchange exchange() {
return new TopicExchange("javainuseExchange");
}
@Bean
Queue dlq() {
return QueueBuilder.durable("deadLetter.queue").build();
}
@Bean
Queue queue() {
return QueueBuilder.durable("javainuse.queue").withArgument("x-dead-letter-exchange", "deadLetterExchange")
.withArgument("x-dead-letter-routing-key", "deadLetter").build();
}
@Bean
Binding DLQbinding() {
return BindingBuilder.bind(dlq()).to(deadLetterExchange()).with("deadLetter");
}
@Bean
Binding binding() {
return BindingBuilder.bind(queue()).to(exchange()).with("javainuse");
}
@Bean
SimpleMessageListenerContainer container(ConnectionFactory connectionFactory, MessageListenerAdapter listenerAdapter) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.setQueueNames("javainuse.queue");
container.setMessageListener(listenerAdapter);
return container;
}
@Bean
MessageListenerAdapter listenerAdapter(ReceiveMessageHandler receiver) {
return new MessageListenerAdapter(receiver, "handleMessage");
}
}
请在下面找到我的class消费消息:
@Component
@Slf4j
@RequiredArgsConstructor
public class ReceiveMessageHandler {
private final SendService sendService;
public void handleMessage(@Valid dto dto) {
String test = null;
//purposely throw null pointer to test dead queue
test.toString();
sendService.sendSomething(dto);
}
当抛出空指针异常时,它会根据 application.yml 配置不断重试,而不是在 max-attempts: 6
6 次后停止。
任何人都可以指出我在这里缺少什么吗?
您正在创建自己的容器 bean,因此未应用 .yml 属性。使用 RetryInterceptorBuilder.stateless() ...
构建重试建议并将其注入侦听器容器(建议链)。
您还需要配置恢复器。
builder.recoverer(new RejectAndDontRequeueRecoverer());
当重试次数用完时,它将队列定向到 DLQ。
我正在学习 spring boot (version 2.2.5.RELEASE) with RabbitMQ 基于在线 resources:
我遇到的问题是,当我故意抛出异常时,它应该只重试 6 次,之后消息应该被移动到死队列,但事实并非如此,因为它不断重试而不停止.
请在下面找到我的 application.yml:
server:
servlet:
contextPath: /test
spring:
rabbitmq:
username: guest
password: guest
listener:
simple:
retry:
enabled: true
initial-interval: 3s
max-attempts: 6
max-interval: 10s
multiplier: 2
请在下面找到rabbitMQ配置class:
@Configuration
public class RabbitMQConfig {
@Bean
TopicExchange deadLetterExchange() {
return new TopicExchange("deadLetterExchange");
}
@Bean
TopicExchange exchange() {
return new TopicExchange("javainuseExchange");
}
@Bean
Queue dlq() {
return QueueBuilder.durable("deadLetter.queue").build();
}
@Bean
Queue queue() {
return QueueBuilder.durable("javainuse.queue").withArgument("x-dead-letter-exchange", "deadLetterExchange")
.withArgument("x-dead-letter-routing-key", "deadLetter").build();
}
@Bean
Binding DLQbinding() {
return BindingBuilder.bind(dlq()).to(deadLetterExchange()).with("deadLetter");
}
@Bean
Binding binding() {
return BindingBuilder.bind(queue()).to(exchange()).with("javainuse");
}
@Bean
SimpleMessageListenerContainer container(ConnectionFactory connectionFactory, MessageListenerAdapter listenerAdapter) {
SimpleMessageListenerContainer container = new SimpleMessageListenerContainer();
container.setConnectionFactory(connectionFactory);
container.setQueueNames("javainuse.queue");
container.setMessageListener(listenerAdapter);
return container;
}
@Bean
MessageListenerAdapter listenerAdapter(ReceiveMessageHandler receiver) {
return new MessageListenerAdapter(receiver, "handleMessage");
}
}
请在下面找到我的class消费消息:
@Component
@Slf4j
@RequiredArgsConstructor
public class ReceiveMessageHandler {
private final SendService sendService;
public void handleMessage(@Valid dto dto) {
String test = null;
//purposely throw null pointer to test dead queue
test.toString();
sendService.sendSomething(dto);
}
当抛出空指针异常时,它会根据 application.yml 配置不断重试,而不是在 max-attempts: 6
6 次后停止。
任何人都可以指出我在这里缺少什么吗?
您正在创建自己的容器 bean,因此未应用 .yml 属性。使用 RetryInterceptorBuilder.stateless() ...
构建重试建议并将其注入侦听器容器(建议链)。
您还需要配置恢复器。
builder.recoverer(new RejectAndDontRequeueRecoverer());
当重试次数用完时,它将队列定向到 DLQ。