programing

Java 구성을 사용하는 @Spring(Boot)의 예약된 작업에 대한 범용 예외 처리기

topblog 2023. 7. 12. 22:12
반응형

Java 구성을 사용하는 @Spring(Boot)의 예약된 작업에 대한 범용 예외 처리기

Spring Boot(ver 1.4.2) 애플리케이션에 예약된 작업이 많이 있으며 @ExceptionHandler 주석이 있는 일반 컨트롤러에서 가능한 것과 같은 하나의 핸들러를 사용하여 모든 예외를 포착하고 싶습니다.이 접근 방식은 스레드화 때문에 @Scheduled 주석으로 정의된 작업에는 적용되지 않습니다.

@Component
public class UpdateJob {
    @Transactional
    @Scheduled(cron = "0 1 0 * * *")
    public void runUpdateUsers() {
        userService.updateUsers();
    }

    @ExceptionHandler
    public void handle(Exception e) {
       // some more logic here
       logger.error(e.getMessage());
    }

 }

@ExceptionHandler는 @Scheduled 메서드에 대해 작동하지 않습니다(그리고 의도하지 않은 것으로 드러났습니다).대신 스프링 부트는 자체 LoggingErrorHandler를 사용합니다.

2016-12-08 15:49:20.016 ERROR 23119 --- [pool-7-thread-1] o.s.s.s.TaskUtils$LoggingErrorHandler    : Unexpected error occurred in scheduled task.

예약된 작업에 대한 기본 예외 처리기를 대체하거나 제공할 수 있습니까?아니면 오류가 추가로 전파되는 전파 오류 처리기로 전환하는 것이 의미가 있습니까?XML 없이 Java 구성만 사용하여 목표를 달성할 수 있는 다른 방법이 있습니까?

XML이 아닌 Java 구성에 기반한 솔루션을 명시적으로 요청하므로 이 질문은 중복되지 않습니다(따라서 XML 구성 없이 Spring Boot 프로젝트에 통합하는 것이 좋습니다).

또한 태스크 스케줄러를 처음부터 구성하는 방법을 보여주는 몇 가지 답변도 있습니다.예를 들어, 이 답변에는 풀 크기, 최대 풀 크기, 대기열 용량도 정의해야 합니다.다음은 매우 광범위한 구성이 필요한 솔루션입니다.설명서에는 다른 측면을 구성하는 방법은 나와 있지만 오류 처리를 지정하는 방법은 나와 있지 않습니다.그러나 봄 부팅 기본값(스레드 풀, 실행자 구성 등)을 최대로 유지할 수 있도록 Java 구성에 필요한 최소한의 노력은 무엇입니까?

다음은 사용자 정의 오류 처리기(Spring 2.0.2)를 설정하는 예입니다.

@Bean
public TaskScheduler taskScheduler() {
    ConcurrentTaskScheduler scheduler = new ConcurrentTaskScheduler();
    scheduler.setErrorHandler(throwable -> { /* custom handler */ });
    return scheduler;
}

당신은 올바른 방향으로 가고 있습니다.PropagatingErrorHandler하지만 당신은 목적을 약간 오해했습니다.이로 인해 예외가 스택 위로 계속 진행되어 이후에는 스케줄링된 작업이 실행되지 않습니다.또한 개인적인 일입니다.TaskUtils액세스할 수 없습니다.

자체적인 솔루션을 구현해야 합니다.ErrorHandler단 한 명의 핸들러만 가질 수 있습니다.Spring에서 더 이상 예외를 기록할 수 없으므로 최소한 예외를 기록하고 싶을 것입니다.

만의 커스텀이하면 ㅠㅠㅠㅠㅠㅠㅠㅠㅠTaskScheduler만의 콩을 당만의것만을들기위해신▁bean위,해만기들▁your.ErrorHandler에서 Spring Boot 구현, 구현org.springframework.boot.task.TaskSchedulerCustomizer@Configuration 클래스에 있습니다.

@Override
public void customize(ThreadPoolTaskScheduler taskScheduler) {
    taskScheduler.setErrorHandler(new CustomErrorHandler());
}

private static class CustomErrorHandler implements ErrorHandler {
    private static final Logger logger = LoggerFactory.getLogger(CustomErrorHandler.class);

    @Override
    public void handleError(Throwable t) {
        logger.error("Scheduled task threw an exception: {}", t.getMessage(), t);
    }
}

ㅠㅠErrorHandler입니다.@FunctionalInterface수 있는 것은 다음과 같습니다.

taskScheduler.setErrorHandler(t -> { /* Handle exception here */});

(이는 Spring Boot 2.1.8을 기반으로 합니다.)

처럼, 댓에나것처럼온글럼▁as.@ExceptionHandlerSpring MVC 컨트롤러용입니다.

단일 스케줄러에 대한 예외 처리 논리를 사용하려는 경우 가장 쉽고 유지 관리 가능한 방법은 이를 시도 캐치 블록으로 래핑하여 오류를 처리하는 것입니다.

다양한 스케줄러에 동일한 오류 처리기를 적용하려면 @M을 따릅니다.Deinum의 제안.

저는 AOP를 사용하면 당신의 문제를 해결할 수 있다고 생각합니다.

스텝

  1. UpdateJob이라는 클래스 생성AOP 및 @Component 및 @Aspect 주석을 사용하여 주석을 달 수 있습니다.
  2. 업데이트 작업 중AOP 클래스는 all()라는 메서드를 만들고 @Pointcut("execution(* com.foo.bar )으로 주석을 달습니다.작업 업데이트.*(...))"
  3. UpdateJob에서 다른 메서드 생성다음에 호출된 AOP 클래스던지기(예외) 또는 무엇이든 하고 @AfterThrowing(포인트컷="all()", 던지기="ex")로 주석 달기
  4. 스택 추적을 인쇄하고 모든 예외가 탐지되었는지 확인합니다.

참고로 나는 개별적인 방법으로 AOP를 작업했고 그 예외를 포착하여 기록했지만 개인적으로는 지금까지 당신이 지정한 사용 사례를 생각해내지 못했습니다.위의 해결책은 단지 제안일 뿐입니다.

@Aspect
@Component
public class UpdateJobAOP {

    @Pointcut("execution(* com.foo.bar.UpdateJob.*(..))")
    public void all()  {}

    @AfterThrowing(pointcut="all()", throwing="ex")
    public void afterThrowing(Exception ex)  {

        // Do what you want
        ex.printStackTrace();

    }

}

XML 구성이 있는 경우 다음과 같이 작동합니다.

<task:annotation-driven scheduler="customThreadPoolTaskScheduler"  />
<bean id="customThreadPoolTaskScheduler" class="org.springframework.scheduling.concurrent.ThreadPoolTaskScheduler">
    <property name="poolSize" value="10" />
    <property name="errorHandler" ref="customScheduledTaskErrorHandler" />
</bean>
<bean id="customScheduledTaskErrorHandler" class="myapp.ScheduledJobErrorHandler"/>
<task:scheduled-tasks scheduler="customThreadPoolTaskScheduler">
     <task:scheduled method="method1" cron="0 0 7 * * *"/>
     <task:scheduled method="method2" cron="0 0 7 * * *"/>
     etc.

는 다음 항목을 대체합니다.<task:scheduler>당신이 가질 수도 있는. 이다을직정다니합의접제음을 직접 하게 되었습니다.ThreadPoolTaskScheduler할 수 .errorHandler.

» myapp.ScheduledJobErrorHandler필수 메서드를 사용하는 클래스:

public class ScheduledJobErrorHandler implements ErrorHandler {

    @Override
    public void handleError(Throwable t) {
         //...
    }

언급URL : https://stackoverflow.com/questions/41041536/universal-exception-handler-for-scheduled-tasks-in-spring-boot-with-java-conf

반응형