서블릿 기반 웹 애플리케이션에서 백그라운드 작업을 실행하는 방법은 무엇입니까?


97

Java를 사용하고 있고 내 애플리케이션에서 서블릿을 계속 실행하고 싶지만 방법을 알 수 없습니다. 내 서블릿에는 매일 데이터베이스에서 사용자 수와 전체 데이터베이스의 총 사용자 수를 제공하는 방법이 있습니다. 그래서 서블릿을 계속해서 실행하고 싶습니다.


"연속 실행"이란 무슨 뜻입니까?
skaffman 2011 년

1
지속적인 달리기 란 무엇을 의미합니까? 앱 서버가 실행되는 동안 실행됩니다
fmucar

2
왜 계속해서 실행해야하는지 이해가 안가요 ... 누군가가 '사용자 수'를 원한다면 그들은 당신의 서블릿 메소드를 호출하고 당신은 그것을 그들에게 주나요?
trojanfoe 2011 년

@trojanfoe 실제로 매일 usercount를 원하므로 매일 서블릿을 수동으로 실행해야하므로 서블릿을 지속적으로 실행하고 싶습니다. 그래서 매일 서블릿을 실행할 필요가 없습니다.
pritsag 2011 년

1
@pritsag : 서블릿은 배치 작업을 실행하는 것이 아니라 사용자 요청을 처리하기 위해 존재합니다.
skaffman 2011 년

답변:


217

당신의 문제는 당신이 서블릿 의 목적을 오해한다는 것입니다 . HTTP 요청에 대해 조치를 취하기위한 것입니다. 매일 한 번 실행되는 백그라운드 작업 만 원합니다.

EJB를 사용할 수 있습니까? 사용하다@Schedule

환경이 EJB (예 : WildFly, JBoss, TomEE, Payara, GlassFish 등과 같은 실제 Java EE 서버)를 지원하는 경우 @Schedule대신 사용하십시오. 여기 몇 가지 예가 있어요.

@Singleton
public class BackgroundJobManager {

    @Schedule(hour="0", minute="0", second="0", persistent=false)
    public void someDailyJob() {
        // Do your job here which should run every start of day.
    }

    @Schedule(hour="*/1", minute="0", second="0", persistent=false)
    public void someHourlyJob() {
        // Do your job here which should run every hour of day.
    }

    @Schedule(hour="*", minute="*/15", second="0", persistent=false)
    public void someQuarterlyJob() {
        // Do your job here which should run every 15 minute of hour.
    }

    @Schedule(hour="*", minute="*", second="*/5", persistent=false)
    public void someFiveSecondelyJob() {
        // Do your job here which should run every 5 seconds.
    }

} 

예, 그게 전부입니다. 컨테이너가 자동으로 픽업 및 관리합니다.

EJB를 사용할 수 없습니까? 사용하다ScheduledExecutorService

환경이 EJB를 지원하지 않는 경우 (즉, 실제 Java EE 서버가 아니라 Tomcat, Jetty 등과 같은 베어 본 서블릿 컨테이너를 사용하지 않는 경우) ScheduledExecutorService. 이것은 ServletContextListener. 다음은 시작 예입니다.

@WebListener
public class BackgroundJobManager implements ServletContextListener {

    private ScheduledExecutorService scheduler;

    @Override
    public void contextInitialized(ServletContextEvent event) {
        scheduler = Executors.newSingleThreadScheduledExecutor();
        scheduler.scheduleAtFixedRate(new SomeDailyJob(), 0, 1, TimeUnit.DAYS);
        scheduler.scheduleAtFixedRate(new SomeHourlyJob(), 0, 1, TimeUnit.HOURS);
        scheduler.scheduleAtFixedRate(new SomeQuarterlyJob(), 0, 15, TimeUnit.MINUTES);
        scheduler.scheduleAtFixedRate(new SomeFiveSecondelyJob(), 0, 5, TimeUnit.SECONDS);
    }

    @Override
    public void contextDestroyed(ServletContextEvent event) {
        scheduler.shutdownNow();
    }

}

직업 클래스는 다음과 같습니다.

public class SomeDailyJob implements Runnable {

    @Override
    public void run() {
        // Do your daily job here.
    }

}
public class SomeHourlyJob implements Runnable {

    @Override
    public void run() {
        // Do your hourly job here.
    }

}
public class SomeQuarterlyJob implements Runnable {

    @Override
    public void run() {
        // Do your quarterly job here.
    }

}
public class SomeFiveSecondelyJob implements Runnable {

    @Override
    public void run() {
        // Do your quarterly job here.
    }

}

Java EE / Servlet 기반 환경에서 java.util.Timer/ 사용에 대해 생각하지 마십시오.java.lang.Thread

마지막 으로 Java EE를 직접 사용 하거나 사용 하지 마십시오 . 이것은 문제의 비결입니다. 동일한 질문에 대한 JSF 관련 답변에서 자세한 설명을 찾을 수 있습니다 . 타이머를 사용하여 예약 된 작업을 위해 JSF 관리 빈에서 스레드 생성 .java.util.Timerjava.lang.Thread


9
@BalucS 감사합니다, 귀하의 솔루션이 저를 도왔고 Java를 처음 접했을 때 나에게 새로운 ScheduledExecutorService에 대해 배웠습니다. 다시 한 번 감사드립니다.
pritsag 2011 년

@BalusC : 클래스 UpdateCounts는 web.xml에 어디에 넣어야합니까?
Ashwin 2012-06-13

1
@Ashwin web.xml배포 설명자 입니다. UpdateCount 클래스 는 배포와 관련이 없으므로 web.xml에
informatik01

12
한 가지 중요한 문제는 실행 프로그램에서 모든 예외ScheduledExecutorService캡처 해야합니다 . run메서드 에서 예외가 이스케이프 하면 실행기가 자동으로 실행을 중지합니다. 이것은 버그가 아닌 기능입니다. 문서를 읽고 인터넷 검색을 통해 공부하세요.
Basil Bourque 2014 년

1
@Agi : scheduler.shutdownNow()예제에 따라 올바르게 호출되지 않으면 발생합니다 . 이것이 호출되지 않으면 스케줄 스레드가 실제로 계속 실행됩니다.
BalusC

4

정기적으로 작업을 실행하려면 Quartz와 같은 라이브러리를 사용하는 것이 좋습니다. 서블릿은 실제로 무엇을합니까? 보고서를 보내나요?


예, 하루에 생성 된 사용자의 수와 데이터베이스의 총 사용자 수를 제공합니다.
pritsag

1
흐우? 시스템의 전체 아키텍처를 설명 할 수 있습니까? 나는 길을 잃었다.
Twister

@Twister im new to java and in learning phase sir, and really do n't know about the servlet.
pritsag

문제는 서블릿에 관한 것이 아닙니다. 당신이 말하는 응용 프로그램은 무엇입니까? (ps : 귀하의 댓글, 특히 내가 답변 한 댓글을 삭제하는 것은 좋지 않습니다.)
Twister

@twister 사용자가 응용 프로그램을 칠 때, 그는 오늘 얼마나 많은 사용자가 생성되었는지, 지금까지 얼마나 많은 사용자가 생성되었는지 등과 같은 모든 세부 정보를 얻고 사용자가 업데이트를받을 수 있도록 백그라운드에서 실행되는 서블릿을 지속적으로 실행하고 싶습니다. . 나는 이것이 적절한 설명이 아니라는 것을 압니다. (ps : 나쁜 생각 이었다는 것을 압니다. 죄송합니다.)
pritsag

3

두 개의 클래스를 구현 startTask()하고 main.

public void startTask()
{
    // Create a Runnable
    Runnable task = new Runnable() {
        public void run() {
            while (true) {
                runTask();
            }
        }
    };

    // Run the task in a background thread
    Thread backgroundThread = new Thread(task);
    // Terminate the running thread if the application exits
    backgroundThread.setDaemon(true);
    // Start the thread
    backgroundThread.start();
}

public void runTask()
{
    try {
        // do something...         
        Thread.sleep(1000);

    } catch (InterruptedException e) {
        e.printStackTrace();
    }
}

3
이것은 웹 응용 프로그램에서 수행하는 방법이 아닙니다. 대신 @BalusC의 답변을 참조하십시오. 그는 여기에서 정확하며 그의 모든 답변을 신뢰할 수 있다고 말하고 싶습니다.
Yoshiya


0

여러 개의 non-jee 컨테이너가 실행중인 프로덕션 시스템에서. 작업 maamgememt에 데이터베이스를 사용하도록 구성 할 수있는 Quartz 스케줄러와 같은 엔터프라이즈 스케줄러가 아닙니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.