복붙노트

[SPRING] Java Spring @ 스케줄 된 작업 두 번 실행

SPRING

Java Spring @ 스케줄 된 작업 두 번 실행

여기서 5 초마다 실행되도록 설정된 간단한 테스트 방법이 있지만 System.out을 보면 이상한 일을하는 것으로 보입니다.

@Scheduled(cron="*/5 * * * * ?")
public void testScheduledMethod() {
     System.out.println(new Date()+" > Running testScheduledMethod...");
}

산출:

Wed Jan 09 16:49:15 GMT 2013 > Running testScheduledMethod...
Wed Jan 09 16:49:15 GMT 2013 > Running testScheduledMethod...
Wed Jan 09 16:49:20 GMT 2013 > Running testScheduledMethod...
Wed Jan 09 16:49:20 GMT 2013 > Running testScheduledMethod...
Wed Jan 09 16:49:25 GMT 2013 > Running testScheduledMethod...
Wed Jan 09 16:49:25 GMT 2013 > Running testScheduledMethod...
Wed Jan 09 16:49:30 GMT 2013 > Running testScheduledMethod...
Wed Jan 09 16:49:30 GMT 2013 > Running testScheduledMethod...

매번 두 번 (실행) 실행되는 이유는 무엇입니까?

해결법

  1. ==============================

    1.문서를 보면이 현상을 명시 적으로 나타내는 메모가 있습니다.

    문서를 보면이 현상을 명시 적으로 나타내는 메모가 있습니다.

    노트는이 링크의 25.5.1 섹션에 있으며 다음과 같이 표시됩니다.

    나는 이것이 단지 현재의 제안 일 뿐이라고 생각하지만, 문제를 더 진단 할 수있는 충분한 정보가 없다고 생각합니다.

  2. ==============================

    2.나는 답을 알아!!

    나는 답을 알아!!

    예약 된 일정을 두 번 초기화하지 마십시오.

    웹 로그에서 약탈 :

    WebApplicationContext 한 번 및 서블릿 한 번

    그래서 servlet.xml에서 이렇게하지 마십시오.

    import resource="classpath:applicationContext.xml"
    
  3. ==============================

    3.컨텍스트 리스너 때문에 발생합니다.

    컨텍스트 리스너 때문에 발생합니다.

    그냥 제거하십시오.

    org.springframework.web.context.ContextLoaderListener

    web.xml에서 작동해야합니다.

  4. ==============================

    4.비슷한 문제가 발생했습니다. 아래 이유 때문일 수 있습니다.

    비슷한 문제가 발생했습니다. 아래 이유 때문일 수 있습니다.

  5. ==============================

    5.나는 비슷한 문제를 겪었고, 나는 이것을 해결했다.

    나는 비슷한 문제를 겪었고, 나는 이것을 해결했다.

    package com.sample.config;
    
    import org.springframework.context.annotation.Configuration;
    import org.springframework.scheduling.annotation.EnableScheduling;
    
    @Configuration
    @EnableScheduling
    public class JobExecutorConfig {
    }
    

    스프링 부트 구성. 그리고 이것을 jobclass로 추가합니다.

    package com.sample.jobs;
    
    import org.slf4j.Logger;
    import org.slf4j.LoggerFactory;
    import org.springframework.beans.factory.annotation.Autowired;
    import org.springframework.scheduling.annotation.Scheduled;
    import org.springframework.stereotype.Component;
    
    @Component
    public class Job {
    
      private final Logger log = LoggerFactory.getLogger(this.getClass());
    
      @Autowired
      MyOtherClass moc;
    
      @Scheduled(fixedRate = 60000) // every 60 seconds
      public void doJob() {
        log.debug("Job running !!!");
        try {
         moc.doSomething()
        } catch (Exception e) {
          log.error(e.getMessage());
        }
        finally {
    
          log.debug("job Done !!!");
        }
    
      }
    
      // examples of other CRON expressions
      // * "0 0 * * * *" = the top of every hour of every day.
      // * "*/10 * * * * *" = every ten seconds.
      // * "0 0 8-10 * * *" = 8, 9 and 10 o'clock of every day.
      // * "0 0/30 8-10 * * *" = 8:00, 8:30, 9:00, 9:30 and 10 o'clock every day.
      // * "0 0 9-17 * * MON-FRI" = on the hour nine-to-five weekdays
      // * "0 0 0 25 12 ?" = every Christmas Day at midnight
    }
    
  6. ==============================

    6.나는이 같은 문제를 안고 있었고 결국에는 루트 컨텍스트와 서블릿 컨텍스트에서 빈이 생성되어 문제가 발생한다는 것을 알게되었습니다.

    나는이 같은 문제를 안고 있었고 결국에는 루트 컨텍스트와 서블릿 컨텍스트에서 빈이 생성되어 문제가 발생한다는 것을 알게되었습니다.

    따라서이 문제를 해결하려면 빈 생성을 적절한 컨텍스트로 분리해야합니다.

    이 답변은 정말 잘 설명하고 내 문제를 해결했습니다.

  7. ==============================

    7.나는 똑같은 문제가 있었다. 해결을 위해 보낸 시간.

    나는 똑같은 문제가 있었다. 해결을 위해 보낸 시간.

    해결 방법은 응용 프로그램이 Tomcat에 두 번 배포하는 것이 었습니다.

    Tomcat을 정리할 때 오류가 발생했습니다.

    server.xml Tomcat 파일 확인하기 같은 것을 두 번 배포했다. 닫히지 않은 "호스트"태그도있었습니다. 이 중 어느 것이 고정되었는지는 모르지만 다시 제대로 작동하게하는 것이 안심하십시오.

  8. ==============================

    8.나는 4.0.3을 사용하고 있는데이 문제가있다. 내 콩 이름 바꾸기로 해결 했어.

    나는 4.0.3을 사용하고 있는데이 문제가있다. 내 콩 이름 바꾸기로 해결 했어.

    에:

    <task:annotation-driven executor="taskExecutor"
        scheduler="taskScheduler" />
    <task:executor id="taskExecutor" pool-size="25" />
    <task:scheduler id="taskScheduler" pool-size="25" />
    

    taskScheduler라는 bean이 발견되지 않아 새로운 인스턴스를 작성한다는 것을 나타내는 일부 정보 로깅을 보았습니다. 그래서 나는 작업 스케줄러의 두 인스턴스가 있다고 생각했습니다.

    이게 너에게 효과가 있는지 알려줘. :)

  9. ==============================

    9.음, 필자의 경우 bean의 @Component annotation은 applicationContext.xml에있다.

    음, 필자의 경우 bean의 @Component annotation은 applicationContext.xml에있다.

    따라서 해결책은 다음과 같은 이유로 bean 정의 (두 번째 줄)를 삭제하는 것입니다.

    : 모든 Spring 관리 객체에서 @Async 및 @Scheduled 주석을 감지 할 수 있으므로 작업 빈을 정의 할 필요가 없으며 두 번 호출됩니다.

  10. ==============================

    10.이 게시물과 Spring Jira에 따르면 Spring Framework Scheduler 구성 요소의 버그입니다.

    이 게시물과 Spring Jira에 따르면 Spring Framework Scheduler 구성 요소의 버그입니다.

  11. ==============================

    11.앱이 WEB 인 경우 서로 다른 두 가지 상황에서 동일한 패키지의 구성 요소를 검색하는지 확인할 수 있습니다 (예 : applicationContext.xml 그리고 나서 다시 some-servlet.xml.

    앱이 WEB 인 경우 서로 다른 두 가지 상황에서 동일한 패키지의 구성 요소를 검색하는지 확인할 수 있습니다 (예 : applicationContext.xml 그리고 나서 다시 some-servlet.xml.

  12. ==============================

    12.

    <context-param>
        <param-name>contextConfigLocation</param-name>
        <param-value>
             /WEB-INF/spring/root-context.xml
             /WEB-INF/spring/security/spring-security.xml
             /WEB-INF/spring/mongo/mongo-config.xml
             /WEB-INF/spring/appServlet/spring-context.xml
        </param-value>
    </context-param>
    <servlet>
        <servlet-name>appServlet</servlet-name>
        <servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
        <init-param>
            <param-name>contextConfigLocation</param-name>
            <param-value>/WEB-INF/spring/appServlet/spring-context.xml</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    

    그건 내 web.xml입니다. 따라서 "/WEB-INF/spring/appServlet/spring-context.xml"이 두 번로드됩니다 (context-param에서는 한 번, servlet-> init-param에서는 한 번).

  13. ==============================

    13.나는 똑같은 상황에 직면했고 이것으로 해결했다.

    나는 똑같은 상황에 직면했고 이것으로 해결했다.

    1) 스케줄러 서비스

    @Service
    public class SchedulerService {
    
        @Autowired
        @Qualifier("WorkerClass")
        private Worker worker;
    
        @Scheduled(cron="0/5 * * * * ?", zone="Asia/Colombo")//zone is a sample
        public void doSchedule() {
            worker.work();
        }
    
    }
    

    2) 노동자 계급

    @Component("WorkerClass")
    public class WorkerClass implements Worker {
    
        @Override
        public void work() {
            doSomething();
        }
    
        protected void doSomething() {
            system.out.pringln("What must I do?");
        }
    
    }
    
  14. ==============================

    14.오늘도 똑같은 문제가있었습니다.

    오늘도 똑같은 문제가있었습니다.

    내 프로젝트에서 내 봄 부팅 응용 프로그램과 스케줄러를 사용하고 있었고 ScheduledTaks 클래스에서 @Component 주석을 사용하고있었습니다. 하지만 @Component 내 클래스에 대한 콩을 대표하고 내 응용 프로그램 클래스에서 코드를 사용하여이 클래스에 대한 다른 빈을 만들었으므로 실수를했습니다.

    public class Application extends SpringBootServletInitializer {
    
      @Override
      protected SpringApplicationBuilder configure(SpringApplicationBuilder application) {
          return application.sources(Application.class);
      }
    
      public static void main(String[] args) throws Exception {
          SpringApplication.run(Application.class, args);
      }
    
      @Bean
      public ScheduledTasks getScheduledTasks() {
        return new ScheduledTasks();
      }
    }
    

    난 그냥이 주석을 제거하고 스케줄러가 완벽하게 작동합니다.

    내 코드 ScheduledTasks 클래스의 예제를 따르십시오.

    public class ScheduledTasks {
      private static final SimpleDateFormat dateFormat = new SimpleDateFormat("HH:mm:ss");
    
      @Scheduled(cron = "00 14 11  * * *")
      public void reportCurrentTime() {
        log.info("The date is: {} " + dateFormat.format(new Date()) );
      }
    }
    

    결과 :

    2016-10-20 11:13:41.298  INFO 6832 --- [           main] s.b.c.e.t.TomcatEmbeddedServletContainer : Tomcat started on port(s): 8080 (http)
    2016-10-20 11:13:41.302  INFO 6832 --- [           main] br.com.Application                       : Started Application in 9.257 seconds (JVM running for 9.676)
    2016-10-20 11:14:00.002  INFO 6832 --- [pool-2-thread-1] br.com.scheduler.ScheduledTasks          : The date is: {} 11:14:00
    
  15. ==============================

    15.나는 동일한 문제를 가지고 있었고, 코드를 살펴 보았고, 여기에있는 모든 것을 시도한 후에, 나는 SpringApplicationBuilder를 두 가지 클래스로 두 번씩 사용했다.

    나는 동일한 문제를 가지고 있었고, 코드를 살펴 보았고, 여기에있는 모든 것을 시도한 후에, 나는 SpringApplicationBuilder를 두 가지 클래스로 두 번씩 사용했다.

  16. ==============================

    16.application.properties 파일에 Spring 부트 애플리케이션에 애플리케이션 시작시 배치 작업을 시작하지 않도록 지시하는 다음 등록 정보를 추가하십시오.

    application.properties 파일에 Spring 부트 애플리케이션에 애플리케이션 시작시 배치 작업을 시작하지 않도록 지시하는 다음 등록 정보를 추가하십시오.

    spring.batch.job.enabled=false
    
  17. ==============================

    17.나는 똑같은 문제가 있었다. 다음과 같이 주석 기반 구성을 사용하고있었습니다.

    나는 똑같은 문제가 있었다. 다음과 같이 주석 기반 구성을 사용하고있었습니다.

    @Configuration
    @EnableScheduling
    public class SchedulerConfig {
    
        @Scheduled(fixedDelay = 60 * 1000)
        public void scheduledJob() { 
            // this method gets called twice... 
        }   
    }
    

    나는 같은 것을 초기화하기 위해 AbstractAnnotationConfigDispatcherServletInitializer를 확장하고 있었다.

    public class SpringWebApplicationInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
    
    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[] { MainConfig.class, SchedulerConfig.class };
    }
    
    @Override
    protected Class<?>[] getServletConfigClasses() {
        return new Class<?>[] {SpringWebConfig.class};
    }
    
    @Override
    protected String[] getServletMappings() {
        return new String[] { "/" };
    }
    
    @Override
    protected Filter[] getServletFilters() {
        final CharacterEncodingFilter encodingFilter = new CharacterEncodingFilter();
        encodingFilter.setEncoding(CHARACTER_ENCODING);
        encodingFilter.setForceEncoding(true);
        return new Filter[] { encodingFilter };
    }
    

    }

    getRootConfigClasses () 메소드에서 SchedulerConfig.class를 제거하면 트릭이 생겼다.

    @Override
    protected Class<?>[] getRootConfigClasses() {
        return new Class<?>[] { MainConfig.class };
    }
    

    이게 도움이 되길 바란다.

  18. ==============================

    18.같은 문제가있었습니다.

    같은 문제가있었습니다.

    필자의 경우 @Service의 @Scheduled 함수를 @Component 주석이있는 새로운 별도의 클래스로 옮겼다. 문제가 해결되었다.

  19. from https://stackoverflow.com/questions/14242310/java-spring-scheduled-tasks-executing-twice by cc-by-sa and MIT license