.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는 개발자가 웹 중심이 아닌 응용 프로그램에 대한 로깅, configuration 및 dependency 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 consoleapplication호스팅해 보기
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 파일에서 코드를 변경합니다.
배포 할 때, 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 이 호환이 잘 되어 별도의 작업이 없었습니다.