복붙노트

[SPRING] 스프링 스케줄러 종료 오류

SPRING

스프링 스케줄러 종료 오류

Tomcat 컨테이너에서 SPRING 기반 스케줄러를 개발하는 동안 webapp 또는 shutdown 서버를 배포 취소 할 때 항상이 logoutput을 얻습니다.

Apr 28, 2010 4:21:33 PM org.apache.catalina.core.StandardService stop
INFO: Stopping service Catalina
Apr 28, 2010 4:21:33 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: A web application appears to have started a thread named [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-1] but has failed to stop it. This is very likely to create a memory leak.
Apr 28, 2010 4:21:33 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: A web application appears to have started a thread named [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-2] but has failed to stop it. This is very likely to create a memory leak.
Apr 28, 2010 4:21:33 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: A web application appears to have started a thread named [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-3] but has failed to stop it. This is very likely to create a memory leak.
Apr 28, 2010 4:21:33 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: A web application appears to have started a thread named [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-4] but has failed to stop it. This is very likely to create a memory leak.
Apr 28, 2010 4:21:33 PM org.apache.catalina.loader.WebappClassLoader clearReferencesThreads
SEVERE: A web application appears to have started a thread named [org.springframework.scheduling.quartz.SchedulerFactoryBean#0_Worker-5] but has failed to stop it. This is very likely to create a memory leak.
.
.
.    
SEVERE: A web application created a ThreadLocal with key of type [org.springframework.core.NamedThreadLocal] (value [Prototype beans currently in creation]) and a value of type [null] (value [null]) but failed to remove it when the web application was stopped. To prevent a memory leak, the ThreadLocal has been forcibly removed.
Apr 28, 2010 4:21:34 PM org.apache.coyote.http11.Http11Protocol destroy
INFO: Stopping Coyote HTTP/1.1 on http-8606

이 문제를 어떻게 해결할 수 있습니까?

감사합니다.

이 리스너를 webapp에 추가합니다.

public class ShutDownHook implements ServletContextListener {
    @Override
    public void contextDestroyed(ServletContextEvent arg0) {
        BeanFactory bf = (BeanFactory) ContextLoader.getCurrentWebApplicationContext();
        if (bf instanceof ConfigurableApplicationContext) {
            ((ConfigurableApplicationContext)bf).close();
        }
    }

    @Override
    public void contextInitialized(ServletContextEvent arg0) {
    }
}

및 내 web.xml

<listener>
    <listener-class>pkg.utility.spring.ShutDownHook</listener-class>
</listener>

그러나 오류는 여전히 존재합니다.

스프링 설정 :

<bean id="run" class="org.springframework.scheduling.quartz.MethodInvokingJobDetailFactoryBean">
    <property name="concurrent" value="false" />
    <property name="targetObject" ref="scheduler" />
    <property name="targetMethod" value="task" />
</bean>

<bean id="cronTrg" class="org.springframework.scheduling.quartz.CronTriggerBean">
    <property name="jobDetail" ref="run" />
    <property name="cronExpression" value="0/5 * * * * ?" />
</bean>

<bean class="org.springframework.scheduling.quartz.SchedulerFactoryBean" destroy-method="destroy">
    <property name="triggers">
        <list>
            <ref bean="cronTrg" />
        </list>
    </property>
</bean>

해결법

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

    1.종료 훅을 추가해야합니다 - Spring 2.5 종료 훅 등록하기를 참조하십시오.

    종료 훅을 추가해야합니다 - Spring 2.5 종료 훅 등록하기를 참조하십시오.

    귀하의 경우에는 아마도이 작업을 수행하는 웹 응용 프로그램에 컨텍스트 리스너를 추가해야합니다 (리스너 + 구현 클래스의 경우 web.xml 항목).

    닫기를 사용하면 가장 쉽습니다.

    ((YourClass)yourObject).close();
    
  2. ==============================

    2.Imho 이것은 석영 스케쥴러의 문제입니다. 나는 https://jira.terracotta.org/jira/browse/QTZ-192라는 버그를 제출했다. 이 문제를 해결하기 위해 콜린 피터스 (Colin Peters)가 제안한 sleep () 솔루션이 저에게 효과적입니다. 종료를 두 번 트리거하지 않으려면 Sleep을 Spring의 SchedulerFactoryBean에 추가 할 수 있습니다.

    Imho 이것은 석영 스케쥴러의 문제입니다. 나는 https://jira.terracotta.org/jira/browse/QTZ-192라는 버그를 제출했다. 이 문제를 해결하기 위해 콜린 피터스 (Colin Peters)가 제안한 sleep () 솔루션이 저에게 효과적입니다. 종료를 두 번 트리거하지 않으려면 Sleep을 Spring의 SchedulerFactoryBean에 추가 할 수 있습니다.

    import org.quartz.SchedulerException;
    import org.springframework.scheduling.quartz.SchedulerFactoryBean;
    
    public class SchedulerFactoryBeanWithShutdownDelay extends SchedulerFactoryBean{
    
      @Override
      public void destroy() throws SchedulerException {
        super.destroy();
        // TODO: Ugly workaround for https://jira.terracotta.org/jira/browse/QTZ-192
        try {
          Thread.sleep( 1000 );
        } catch( InterruptedException e ) {
          throw new RuntimeException( e );
        }
      }
    }
    
  3. ==============================

    3.여기 온라인 해결책을 찾은 사람 중 아무도 내 솔루션이 아닙니다. 이것은 특히 Spring & Tomcat으로 Quartz 스케쥴러를 종료하는 것입니다.

    여기 온라인 해결책을 찾은 사람 중 아무도 내 솔루션이 아닙니다. 이것은 특히 Spring & Tomcat으로 Quartz 스케쥴러를 종료하는 것입니다.

    내 설명은 여기에있다 : http://forum.springsource.org/showthread.php?34672-Quartz-doesn-t-shutdown&p=370060#post370060

    근본적으로 문제는 Quartz가 완전히 종료 할 시간이없고 waitForJobsToCompleteOnShutdown 인수가 도움이되지 않는다는 것입니다. 그래서 webapp에 사용자 지정 종료 수신기를 구현하고 스케줄러에 대한 참조를 얻은 다음 수동으로 종료합니다. 계속하기 전에 1 초 동안 기다리십시오.

    public class ShutDownHook implements ServletContextListener
    {
    
        @Override
        public void contextDestroyed(ServletContextEvent arg0)
        {
            try
            {
                // Get a reference to the Scheduler and shut it down
                WebApplicationContext context = ContextLoader.getCurrentWebApplicationContext();
                Scheduler scheduler = (Scheduler) context.getBean("quartzSchedulerFactory");
                scheduler.shutdown(true);
    
                // Sleep for a bit so that we don't get any errors
                Thread.sleep(1000);
            }
            catch (Exception e)
            {
                e.printStackTrace();
            }
        }
    
        @Override
        public void contextInitialized(ServletContextEvent arg0)
        {
        }
    
  4. ==============================

    4.스레드가 종료되도록하는 유일한 방법은 스레드를 인터럽트하여 조인하는 것입니다.

    스레드가 종료되도록하는 유일한 방법은 스레드를 인터럽트하여 조인하는 것입니다.

    이것은 quartz [?]에서 메모리 누수를 방지하는 방법에 대한 질문에 대한 답변에서 설명한대로 org.quartz.InterruptableJob을 구현하여 수행 할 수 있습니다.

  5. from https://stackoverflow.com/questions/2730354/spring-scheduler-shutdown-error by cc-by-sa and MIT license