재우니의 블로그

.NET Core 6 으로 Quartz 스케줄러 활용하여 Window Service 구현하기

 

이 기사에서는 Quartz Cron 표현식을 사용하여 .NET Core로 Window Service 를 만드는 방법을 배웁니다. 그리고 서버 시스템에서 Windows Service 로 응용 프로그램을 호스팅합니다.

 

1 단계

시작하려면 .NET core console application 템플릿으로 프로젝트를 만드세요.

2 단계

Nuget Package Manager. 를 사용하여 Host Builder 에 필요한 패키지를 아래와 같이 2가지를 설치합니다.

 

 

Host Builder 소개

Host Builder는 개발자가 웹 중심이 아닌 응용 프로그램에 대한 로깅, configurationdependency injection 과 같은 cross-cutting 문제(concerns) 를 쉽게 설정할 수 있도록 해 주는 새로운 "generic" Host 입니다. 

 

예를 들어 대기열에서 메시지를 처리하는 등 background processing tasks 을 실행해야 하는 부분을 console application  에서 이를 사용될 수 있습니다. 이러한 유형의 서비스는 이제 cloud-native, container-based architecture 에서 매우 일반적입니다.

 

 

 

Step 3

 

 Nuget Package Manager 를 사용하여 Quartz에 필요한 패키지를 설치합니다.

 

또는 아래와 같이 Package Manager Console 을 사용하여 Quartz를 설치할 수도 있습니다.

 

NuGet\Install-Package Quartz -Version 3.4.0

 

4단계

패키지 설치가 완료되면 특정 시간 후에 실행하는 스케줄러 기능을  작성할 수 있습니다. 특정 시간에 로그를 남기기 위한 개발 코드를 아래와 같이 program.cs 파일에 기재 합니다.

 

class Program {
    static async Task Main(string[] args) {
        IHost Host = CreateHostBuilder(args).Build();
        await Host.RunAsync();
    }
    public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args).ConfigureServices(services => {
        ConfigureQuartzService(services);
        services.AddScoped < ITaskLogTime, TaskLogTime > ();
    });
    private static void ConfigureQuartzService(IServiceCollection services) {
        // Add the required Quartz.NET services
        services.AddQuartz(q => {
            // Use a Scoped container to create jobs.
            q.UseMicrosoftDependencyInjectionJobFactory();
            // Create a "key" for the job
            var jobKey = new JobKey("Task1");
            // Register the job with the DI container
            q.AddJob < Task1 > (opts => opts.WithIdentity(jobKey));
            // Create a trigger for the job
            q.AddTrigger(opts => opts.ForJob(jobKey) // link to the Task1
                .WithIdentity("Task1-trigger") // give the trigger a unique name
                .WithCronSchedule("0/5 * * * * ?")); // run every 5 seconds
        });
        // Add the Quartz.NET hosted service
        services.AddQuartzHostedService(q => q.WaitForJobsToComplete = true);
    }
}

 

Cron Trigger 소개

quartz 을 사용하므로 cron trigger 를 사용할 수 있습니다. Cron은 오랫동안 존재해 온 UNIX 도구이며, 스케줄링 기능에 강력하고 또한 입증되어 있습니다. CronTrigger 클래스는 cron의 스케줄링 기능을 기반으로 합니다.

POC는 아래와 같이 표현식(expression)을 사용하여 5초 동안 cron trigger 를 추가했습니다.

 

"0/5 * * * * ?"

 

trigger  를 생성하고 아래 코드와 같이 quartz 에 추가합니다.

 

 

private static void ConfigureQuartzService(IServiceCollection services) {
    // Add the required Quartz.NET services
    services.AddQuartz(q => {
        // Use a Scoped container to create jobs.
        q.UseMicrosoftDependencyInjectionJobFactory();
        // Create a "key" for the job
        var jobKey = new JobKey("Task1");
        // Register the job with the DI container
        q.AddJob < Task1 > (opts => opts.WithIdentity(jobKey));
        // Create a trigger for the job
        q.AddTrigger(opts => opts.ForJob(jobKey) // link to the Task1
            .WithIdentity("Task1-trigger") // give the trigger a unique name
            .WithCronSchedule("0/5 * * * * ?")); // run every 5 seconds
    });
    // Add the Quartz.NET hosted service
    services.AddQuartzHostedService(q => q.WaitForJobsToComplete = true);
}

 

 

5단계

응용 프로그램을 빌드하고 실행합니다. bin 폴더에 아래와 같이 exe 파일을 실행합니다. cron 표현식에 따라 5초마다 현재 시간 동안 log.txt 파일에 로그 내용이 쌓에게 됩니다.

 

 

 

log.txt 파일을 열면 아래와 같이 로그 내역이 5초마다 스케줄링 되어 기재된 것을 보실 수 있습니다.

 

6단계

exe 파일을 사용하여 직접 실행하는 수동으로 응용 프로그램을 실행합니다. 이제 서버에서 애플리케이션을 이렇게 실행하는 것이 좋은 방법이라고 생각할 수도 있지만 불편할 수도 있습니다. 그래서 이를 편리하게 사용하기 위해서 아래와 같이 설치 및 코드를 변경해 봅시다.

 

 

 

Windows service dotnet core console application 호스팅해 보기

 

console application 을 window service 로 호스팅하려면 아래 단계에 맟게 설정해야 합니다.

 

 

코드 변경 필수

window service console application 을 지원하려면 CreateHostBuilder 에서 UseWindowsService() 메소드를 허용해야 합니다.

 

window service 를 사용하려면 NuGet 패키지를 설치해야 합니다.

 

'Microsoft.AspNetCore.Hosting.WindowsServices'

 

command 으로 설치하려면 “Install-Package Microsoft.AspNetCore.Hosting.WindowsServices - Version” 을 사용하십시오.

 

 

Note

.NET core 버전에 맞게 패키지를 설치해야 합니다. Program.cs 파일에서 코드를 변경합니다.

public static IHostBuilder CreateHostBuilder(string[] args) => Host.CreateDefaultBuilder(args).UseWindowsService().ConfigureServices(services => {
    ConfigureQuartzService(services);
    services.AddScoped <ITaskLogTime, TaskLogTime> ();
});

 

코드 변경이 완료되면 Release mode 에서 애플리케이션을 게시(Publish) 합니다.

 

애플리케이션을 게시(Publish)한 후 관리자 모드에서 명령 프롬프트(Command Prompt )를 엽니다.

 

서비스 생성 명령어 > SC CREATE "ServiceName" binpath="D:\Published \application\path\application.exe"

서비스 제거 명령어 > SC DELETE ServiceName

 

일단 서비스 생성 명령어를 실행하면, service 가 생성됩니다. win + R > services.msc 입력 > Enter 키를 눌러서 확인해 봅니다.

 

 

Service  는 생성하는 동안 저희가 지정 입력한 이름("ServiceName") 이 Services 목록에 표시됩니다. 예제에서는 Window Service POC 라고 서비스명을 기재해서 생성하여 위와 같이 서비스 목록에 보였습니다.

 

SC CREATE "Window Service POC" binpath="D:\Published \application\path\application.exe"

 

여기에서 Services 를 시작 및 중지하기도 하고, 요구 사항에 따라 환경구성을 변경하기도 합니다. (즉, 다른 user 에 의한 login, 자동(automatic) 또는 수동(manual))

 

 

 

서비스 이점

  • 서버 관리자는 서버에서 수동으로 exe 파일을 실행할 필요가 없습니다.
  • 서버 관리자는 요구 사항에 따라 다른 자격 증명을 설정할 수 있습니다.
  • 자동(automatic) 또는 수동(manual) 으로 시작(Start)을 설정할 수 있습니다. 따라서 서버가 다운 되거나 윈도우를 다시 시작될 때마다 자동으로 서비스를 시작하는지 확인할 필요가 없습니다.

 

 

 

번역 사이트

 

https://www.c-sharpcorner.com/article/create-window-service-in-net-core/?fbclid=IwAR392iC18Da5jHOH8hlemDoArOdYMmHfMgfwjzWogs-nwQxC0isCNOts1YU/download/WindowService_POC.zip/download/WindowService_POC.zip 

 

Create Window Service In .NET Core

Schedular job in .net core console application host as a windows service.

www.c-sharpcorner.com

 


 

위의 블로그를 기반으로 사용하다가 추가적으로 설명이 필요한 부분을 기술 했습니다.

 

 

배포 할 때, Target location 을 지정하면 해당 경로에 배포 파일이 제공됩니다.

 

 

TaskLogTime.cs 파일 내에 log.txt 파일 경로 지정한 부분이 있는데요. 저는 전체 물리적 경로를 전부 기재하였으며, 해당 경로에  log.txt 파일까지 직접 만들었습니다. 

 

이유는 Window service 에서 이를 추가해서 Start(시작) 을 했지만, log.txt 파일에 로그 내용이 기재되지 않은 현상이 발생되어 상대경로가 아닌 절대경로를 변경해서 배포하여 서비스에 등록 후 실행 한 결과 log.txt 에 5초마다 내용이 append 된 것을 확인 하였습니다.

 

 

블로그 내용에 맞게 5가지를 nuget 으로 부터 다운로드 받았습니다.

 

 

 

블로그 내에서도 원본 소스를 제공해 주며, 이는 core 5 버전으로 구성되어 개발되어 있습니다. 여기 첨부된 파일은 core 6 버전으로 되어 있으며, 코드는 차이 없습니다. core 5 와 6 이 호환이 잘 되어 별도의 작업이 없었습니다.

 

WindowService_POC.zip
0.01MB