예약 된 작업을 실행하는 가장 좋은 방법


229

오늘 우리는 ASP.NET 웹 사이트에 대해 예약 된 작업을 실행하기위한 콘솔 응용 프로그램을 만들었습니다. 그러나이 접근법은 약간 오류가 발생하기 쉽고 유지 관리가 어렵다고 생각합니다. 예약 된 작업을 어떻게 수행합니까 (Windows / IIS / ASP.NET 환경에서)

최신 정보:

작업 예 :

  • 데이터베이스의 이메일 큐에서 이메일 보내기
  • 데이터베이스에서 오래된 오브젝트 제거
  • Google 애드워즈에서 통계를 검색하고 데이터베이스에서 테이블을 채 웁니다.

실행중인 작업의 예는 무엇입니까?
JeffO


Plesk가있는 경우 vbs를 작성하여 작업 스케줄러에 광고 할 수 있습니다. net24.co.nz/kb/article/AA-00213/13/Shared-Hosting/ASP-ASP.NET/…
HasanG

답변:


74

웹 사이트에 대한 모든 내 작업 (예약해야 함)은 웹 사이트 내에 유지되며 특수 페이지에서 호출됩니다. 그런 다음이 페이지를 너무 자주 호출하는 간단한 Windows 서비스를 작성했습니다. 페이지가 실행되면 값을 반환합니다. 수행해야 할 작업이 더 많다는 것을 알고 있으면 바로 페이지를 다시 실행하고, 그렇지 않으면 잠시 동안 실행합니다. 이것은 저에게 정말 효과적이며 모든 작업 논리를 웹 코드와 함께 유지합니다. 간단한 Windows 서비스를 작성하기 전에 Windows 스케줄러를 사용하여 x 분마다 페이지를 호출했습니다.

이를 실행하는 또 다른 편리한 방법은 Pingdom 과 같은 모니터링 서비스를 사용하는 것 입니다. http 확인을 서비스 코드를 실행하는 페이지로 지정하십시오. 페이지에 결과가 표시되도록하여 Pingdom을 트리거하여 무언가 잘못되었을 때 경고 메시지를 보내도록 할 수 있습니다.


3
이것이 내가 끝낸 해결책입니다. 사용자 정의 웹 서비스 대신 Windows 스케줄러 + 컬을 사용합니다. Windows 서비스를 사용하면 어떤 이점이 있습니까?
Niels Bosma

16
캐시 항목 만료 기술을 살펴 보셨습니까? 예정된 서비스의 구현이 훨씬 더 이상적인 것 같습니다 : codeproject.com/KB/aspnet/ASPNETService.aspx
Richard Clayton

10
악의적 인 사용자 (또는 검색 엔진 스파이더)가이 페이지를 호출하지 못하게하여 예약 된 작업을 실행시키는 방법은 무엇입니까?
UpTheCreek

8
정적 타임 스탬프를 웹 앱에 저장하고 타임 스탬프가 설정되지 않았거나 (첫 번째 호출) 마지막 호출 이후 올바른 시간이 만료 된 경우에만 실행하여 악의적 인 호출을 중지 할 수 있습니다.
Rob Kent

5
IP 주소가 내부 주소인지 여부를 확인하여 내 URL에 대한 악의적 인 호출을 중지합니다. 조직 내부에 있지 않으면 아무것도 반환하지 않으며 아무 것도 수행하지 않습니다.
user1408767

128

Jeff Atwood가 Stackoverflow를 위해 사용한이 기술 은 내가 만난 가장 간단한 방법입니다. ASP.NET의 캐시 시스템에 구축 된 "캐시 항목 제거"콜백 메커니즘에 의존합니다.

업데이트 : Stackoverflow 가이 방법을 능가했습니다. 웹 사이트가 실행되는 동안에 만 작동하지만 많은 사람들에게 유용한 매우 간단한 기술입니다.

Quartz.NET 도 확인하십시오


12
응용 프로그램이 실행되고 있지 않지만 예약 된 작업이 필요한 경우 어떻게됩니까?
MichaelGG

2
또한이 시간 동안 작업을 실행하는 데 시간이 걸리면 사용자 경험이 느려질 수 있습니다. 나는 사용자가 나를 위해 유지 보수 / 작업을 생성하지 않는 것을 선호합니다.
Brettski

5
이것은 지옥처럼 무섭다! 무엇이든 응용 프로그램 실행을 중지시킬 수 있으며 다음 사용자 요청시에만 다시 시작될 수 있습니다. 그 시간 사이에 작업이 실행되지 않습니다!
teedyay

43
원래 블로그 게시물에 대한 의견에서 오늘 주목 한 점 : No, we’ve switched to a dedicated task. We definitely outgrew this technique. I do think it’s fine for small sites though!-Jeff Atwood
Joel Coehoorn

3
-1이 방법에는 큰 결함이 있습니다. 응용 프로그램이 재활용 될 때마다 'CacheItemRemoved'이벤트가 발생하고 예약 된 작업이 실행됩니다. 생산 현장에서는 하루에 몇 번 발생할 수 있습니다. 작업을 매주 실행하려면 좋지 않습니다.
Steven de Salas

30

사용자 정의 Windows 서비스를 작성하십시오 .

예정된 콘솔 앱으로 미션 크리티컬 한 작업을 설정했으며 유지 관리가 어렵다는 것을 알게되었습니다. 몇 분마다 DB의 일정을 확인하는 '하트 비트'가 포함 된 Windows 서비스를 만들었습니다. 정말 잘되었습니다.

그럼에도 불구하고, 여전히 중요하지 않은 대부분의 유지 관리 작업에 예약 된 콘솔 앱을 사용합니다. 고장 나지 않았다면 고치지 마십시오.


7
참고로 링크가 이제 죽었습니다.
Charles Burns

1
@CharlesBurns, 당신은 항상 archive.org와 죽은 링크를 탐색 할 수 있습니다 : web.archive.org/web/20090919131944/http://www.dotheweb.net/…
Nikolay Kostov

17

나는 이것이 관련된 모든 사람들에게 쉬운 것으로 나타났습니다.

  • DoSuchAndSuchProcess와 같은 웹 서비스 메소드 작성
  • 이 웹 메서드를 호출하는 콘솔 앱을 만듭니다.
  • 작업 스케줄러에서 콘솔 앱을 예약하십시오.

이 방법론을 사용하면 모든 비즈니스 로직이 웹 앱에 포함되어 있지만 Windows 작업 관리자 또는 다른 상업용 작업 관리자의 안정성을 통해 실행 보고서와 같은 반환 정보를 기록 할 수 있습니다. 페이지에 게시하는 대신 웹 서비스를 사용하면 웹 서비스에서 반환 데이터를 쉽게 얻을 수 있기 때문에 약간의 이점이 있습니다.


10

휠을 재발 명하는 이유는 스레딩 및 타이머 클래스를 사용하는 것입니다.

    protected void Application_Start()
    {
        Thread thread = new Thread(new ThreadStart(ThreadFunc));
        thread.IsBackground = true;
        thread.Name = "ThreadFunc";
        thread.Start();
    }

    protected void ThreadFunc()
    {
        System.Timers.Timer t = new System.Timers.Timer();
        t.Elapsed += new System.Timers.ElapsedEventHandler(TimerWorker);
        t.Interval = 10000;
        t.Enabled = true;
        t.AutoReset = true;
        t.Start();
    }

    protected void TimerWorker(object sender, System.Timers.ElapsedEventArgs e)
    {
        //work args
    }

7
타이머를 시작하기 위해 스레드를 생성 할 필요가 없습니다.
Zyo

4
나도 그것이 이상적인 해결책이라고 생각하지 않습니다.
Idan Shechter

12
@IdanShechter 왜 이것이 이상적인 해결책이 아니라고 생각하는지 설명하는 것이 좋을 것입니다.
Omu

2
스레드는 HttpRequest가 아니기 때문에 문제가 될 수 있습니다. HttpRequest와 관련된 일부 데이터는 null 일 수 있습니다. 예를 들어 HttpRequest .ApplicationPath입니다. 작업이 올바르게 작성되면 작동합니다. 또 다른 문제는 응용 프로그램 풀을 다시 시작하는 것입니다. 풀이 너무 자주 다시 시작되면 (메모리 누수 ...) 작업자는 절대 실행되지 않습니다.
Tomas Kubes

2
여러 인스턴스가 실행중인 경우 (예 :로드 밸런싱)이 솔루션을 원하지 않을 것입니다 (일부 작업은 동일 함)
Illidan

8

Windows 스케줄러를 사용하여 웹 페이지를 실행하십시오.

악의적 인 사용자 또는 검색 엔진 스파이더가이를 실행하지 못하도록하려면 예약 된 작업을 설정할 때 간단히 쿼리 문자열을 사용하여 웹 페이지를 호출하십시오. 예 : mypage.aspx? from = scheduledtask

그런 다음 페이지로드시 간단히 조건을 사용하십시오. if (Request.Querystring [ "from"] == "scheduledtask") {// executetask}

이렇게하면 검색 엔진 스파이더 나 악의적 인 사용자가 예약 된 작업을 실행할 수 없습니다.


5
더 좋은 방법은 마술 구문보다 보안 성이 약간 더 높은 쿼리 문자열을 실제로 검증하는 솔트 해싱 알고리즘을 사용하는 것입니다. 요청은 mypage.aspx? salt = foo & hash = 1223523jbhdgu13t1과 같은 것입니다. 서버와 클라이언트 모두에 동일한 해싱 알고리즘이 있어야합니다. 서버에 하드 제한을 추가하십시오. 실행될 때 저장하고 너무 빨리 실행되지 않도록하십시오. 그래도 편집증이 될 수 있습니다.
Nenotlep

14
더 안전한 경우 Windows 스케줄러를 사용하여 요청이 서버 자체에서 오는지 확인하는 웹 페이지를 실행하십시오. Request.IsLocal>> 서버 자체 만 예약 된 작업을 실행할 수 있습니다.
음모

당신의 접근 방식에서 더 많은 경험이 있습니까? 앱과 비슷한 유형의 서비스를 개발하려고했는데 예약 된 작업이나 크론이있는 페이지를 호출하는 것이 더 나은지 캐시 시스템을 사용할지 여부를 결정할 수 없습니다.
JayDee


3

또한 응용 프로그램에서 SQL SERVER를 사용하는 경우 SQL 에이전트를 사용하여 작업을 예약 할 수 있습니다. 여기에는 데이터 중심의 이메일 코드 (이메일 알림, 예정된 유지 보수, 제거 등)가 자주 발생합니다. SQL 에이전트에 내장 된 유용한 기능은 중요한 작업이 실패 할 경우 경고 할 수있는 실패 알림 옵션입니다.


2

어떤 종류의 예약 된 작업을 의미하는지 잘 모르겠습니다. "시간마다, foo.xml을 새로 고치십시오"유형의 작업과 같은 것을 의미하는 경우 Windows 예약 된 작업 시스템을 사용하십시오. ( "at"명령 또는 컨트롤러를 통해) 콘솔 응용 프로그램을 실행하거나 프로세스를 시작하는 특수 페이지를 요청하십시오.

편집 : 추가해야합니다. 이것은 IIS 응용 프로그램을 예약 된 지점에서 실행하는 좋은 방법입니다. 따라서 30 분마다 DB를 확인하고 일부 데이터에 대해 사용자에게 전자 메일 미리 알림을 보내려는 경우 예약 된 작업을 사용하여이 페이지를 요청하여 IIS 처리 작업을 수행 할 수 있습니다.

요구 사항이 더 복잡한 경우 Windows 서비스를 작성하고 필요한 처리를 수행하기 위해 루프를 실행하는 것을 고려할 수 있습니다. 또한 확장 또는 관리 목적으로 코드를 분리 할 수 ​​있다는 이점이 있습니다. 단점은 Windows 서비스를 처리해야합니다.


2

서버를 소유 한 경우 Windows 작업 스케줄러를 사용해야합니다. AT를 사용합니까? 옵션을 보려면 명령 행에서

그렇지 않으면, 웹 기반 환경에서 시간 간격을두고 특정 페이지에 요청을하기 위해 다른 머신을 설정하는 것과 같은 불쾌한 작업을 수행해야 할 수도 있습니다.


2

ASP.NET 프로젝트에서 Abidar를 성공적으로 사용 했습니다 (여기에는 배경 정보가 있습니다 ).

이 방법의 유일한 문제점은 ASP.NET 웹 응용 프로그램이 메모리에서 언로드되면 (즉, 사용량이 적기 때문에) 작업이 실행되지 않는다는 것입니다. 내가 시도한 한 가지 방법은 5 분마다 웹 응용 프로그램을 실행하여 살아있는 상태로 유지하는 작업을 만드는 것이지만 제대로 작동하지 않는 것처럼 보이므로 이제 Windows 스케줄러와 기본 콘솔 응용 프로그램을 사용하여 대신 작업을 수행하고 있습니다.

이상적인 솔루션은 Windows 서비스를 만드는 것이지만 불가능할 수도 있습니다 (예 : 공유 호스팅 환경을 사용하는 경우). 또한 유지 관리 측면에서 웹 응용 프로그램 내에서 작업을 유지하기가 훨씬 쉽습니다.


1

다른 방법이 있습니다.

1) 작업이 DUE이거나 기한이 지난 작업을 시작하는 "하트 비트"웹 스크립트를 만듭니다.

2) 웹 스크립트에 부딪 히고 규칙적인 간격으로 강제 실행되도록 예약 된 프로세스를 작성하십시오 (같은 웹 서버에서 선호). (예 : IE를 사용하여 히트 비트 스크립트를 자동으로 시작하는 Windows 예약 작업 또는 사용자)

태스크 코드가 웹 스크립트 내에 포함되어 있다는 사실은 순전히 코드 웹 응용 프로그램 코드베이스 (가정은 서로 의존적이라고 가정). 웹 개발자가 관리하기가 더 쉽습니다. .

다른 방법은 모든 일정이 자체적으로 작동하고 실행 파일 자체를 예약 된 작업으로 실행하는 실행 가능한 서버 스크립트 / 프로그램을 만드는 것입니다. 이를 통해 웹 응용 프로그램과 예약 된 작업을 근본적으로 분리 할 수 ​​있습니다. 따라서 웹앱 / 데이터베이스가 다운되었거나 액세스 할 수없는 경우에도 예약 된 작업을 실행해야하는 경우이 방법을 사용해야합니다.


1
@Matias, 예약 된 프로세스가 실제 작업을 수행하는 이유는 무엇입니까?
LukeH

1

'ThreadPool.RegisterWaitForSingleObject'메소드를 사용하여 간격마다 코드를 실행하는 Windows 서비스를 쉽게 작성할 수 있습니다. 정말 매끄럽고 설정하기가 쉽습니다. 이 방법은 프레임 워크에서 타이머를 사용하는보다 효율적인 방법입니다.

자세한 내용은 아래 링크를 참조하십시오.

Windows 서비스를 사용하여 .NET에서 주기적 프로세스 실행 :
http://allen-conway-dotnet.blogspot.com/2009/12/running-periodic-process-in-net-using.html


0

우리는 콘솔 응용 프로그램도 사용합니다. Log4net과 같은 로깅 도구를 사용하면 실행을 제대로 모니터링 할 수 있습니다. 또한 올바르게 설계된 경우 두 코드간에 동일한 코드 라이브러리를 공유 할 수 있으므로 웹 페이지보다 유지 관리가 더 어려운 방법이 확실하지 않습니다.

이러한 작업이 시간에 따라 실행되지 않으면 웹 사이트의 관리 섹션에 대기열 역할을하는 웹 페이지가있을 수 있습니다. 사용자는 작업 실행 요청을하고 MyProcessQueue 테이블에 빈 날짜 스탬프 레코드를 삽입하며 예약 된 작업은 MyProcessQueue에서 새 레코드에 대해 X 분마다 확인합니다. 이렇게하면 고객이 원하는 경우에만 실행됩니다.

그 제안이 도움이 되길 바랍니다.


0

한 가지 옵션은 Windows 서비스를 설정하고 예약 된 작업을 호출하도록하는 것입니다.

winforms에서 Timers를 사용했습니다 .ASP.NET에서 이것이 잘 작동한다고 생각하지 않습니다.


-1

.NET을위한 새로운 작업 스케줄러 클래스 라이브러리

참고 :이 라이브러리가 작성되었으므로 Microsoft는 Windows Vista 용 새 작업 스케줄러 (Task Scheduler 2.0)를 도입했습니다. 이 라이브러리는 작업 스케줄러 1.0 인터페이스의 래퍼로서 Vista에서 계속 사용할 수 있으며 Windows XP, Windows Server 2003 및 Windows 2000과 호환됩니다.

http://www.codeproject.com/KB/cs/tsnewlib.aspx


삭제 해주세요. 아래 답변되었습니다. 복제
Fandango68
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.