自从我的项目开始以来,有时会在收到几条RabbitMQ消息后收到臭名昭著的CJCommunicationsException
。由于对MySQL服务器几乎没有控制权,因此我需要退出/重新启动Spring Boot应用程序才能摆脱该异常。
由于上下文不涉及@Controller
或@RestController
(我正在使用RabbitMQ侦听器),因此无法使用@ControllerAdvice
和@ExceptionHandler
捕获异常。我正在尝试做类似的事情:
public static void main(String... args) throws Exception {
while(true){
try(ConfigurableApplicationContext ctx = SpringApplication.run(Application.class, args)) {
CompletableFuture<Throwable> throwableFuture = new CompletableFuture<>();
Thread.setDefaultUncaughtExceptionHandler(
(thread, throwable) -> throwableFuture.completeExceptionally(throwable));
throwableFuture.get();
} catch (Exception | VirtualMachineError t) {
//log error
}
}
}
如here所述,但是由于org.apache.catalina.core.StandardWrapperValve.invoke
中的嵌入式Tomcat捕获了异常,因此this answer指出,这无济于事。
我该如何克服呢?
答案 0 :(得分:0)
您似乎应该使用异常策略创建org.springframework.util.ErrorHandler
类型的自定义bean(对于org.springframework.amqp.rabbit.listener.ConditionalRejectingErrorHandler
,它是org.springframework.amqp.rabbit.listener.FatalExceptionStrategy
),并将其传递到您的容器工厂。
如果没有当前配置,很难为您提供有效的配置,但是您的设置可能看起来像这样:
@Configuration
@EnableRabbit
public class RabbitMqConfiguration {
// ... other @Bean-s
@Bean
public SimpleRabbitListenerContainerFactory exportPartyListenerContainer() {
SimpleRabbitListenerContainerFactory listenerContainer = new SimpleRabbitListenerContainerFactory();
//... custom setup
listenerContainer.setErrorHandler(errorHandler());
return listenerContainer;
}
@Bean
public ErrorHandler errorHandler() {
return new ConditionalRejectingErrorHandler(new YourCustomExceptionStrategy());
}
}
实施:
public class YourCustomExceptionStrategy extends DefaultExceptionStrategy {
//.. some @Autowire-s if you need
@Override
public boolean isFatal(Throwable t) {
// ... your handling
}
}
也许值得实现您的自定义org.springframework.util.ErrorHandler
并将其传递给容器工厂。