前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >.NET6用起来-Quartz.NET

.NET6用起来-Quartz.NET

作者头像
李明成
发布2022-05-16 14:28:19
1.5K0
发布2022-05-16 14:28:19
举报
文章被收录于专栏:dotNET知音dotNET知音

Quartz.NET是一个功能齐全的开源作业调用系统,大大小小的应用程序都可使用。

创建一个asp.NET core web项目,使用quartz.NET的作业,定时调用远程接口是否能正常访问,发生异常调用飞书消息接口,把异常发送给指定的同事飞书。

1.准备工作

定义一个作业调用的服务接口ICheckService

代码语言:javascript
复制
    public interface ICheckService
    {
        Task ConnectRemoteApi(ConnectRemoteApiInput input);
    }

实现类CheckService

代码语言:javascript
复制
public class CheckService : ICheckService
    {
        private readonly ILogger<CheckService> _logger;
        private readonly IHttpClientFactory _httpClientFactory;
        private readonly AppSetting _appSetting;
        public CheckService(ILogger<CheckService> logger, IHttpClientFactory httpClientFactory
            , IOptionsMonitor<AppSetting> options)
        {
            _logger = logger;
            _httpClientFactory = httpClientFactory;
            _appSetting = options.CurrentValue;
        }

        public async Task ConnectRemoteApi(ConnectRemoteApiInput input)
        {

            var para = new SecurityCodeInput()
            {
                Code = input.InnerCode,
                Inner = input.Inner
            };

            HttpClient client = _httpClientFactory.CreateClient();
            var paraContent = new StringContent(JsonSerializer.Serialize(para),
                encoding: Encoding.UTF8,
                mediaType: "application/json");

            try
            {
                using var httpResponse = await client.PostAsync(_appSetting.CheckUrl, paraContent);
                var result = await httpResponse.Content.ReadAsStringAsync();
                _logger.LogInformation(httpResponse.StatusCode.ToString());
            }
            catch (Exception ex)
            {
                //通过飞书发送消息给指定的人员
                _logger.LogInformation(ex.Message);

            }
        }
    }

实现Ijob接口

代码语言:javascript
复制
public class CheckRemoteApiJob : IJob
    {
        private readonly ICheckService _checkService;
        private readonly AppSetting _appSetting;
        public CheckRemoteApiJob(ICheckService checkService, IOptionsMonitor<AppSetting> options)
        {
            _checkService = checkService;
            _appSetting = options.CurrentValue;
        }

        public async Task Execute(IJobExecutionContext context)
        {
            await _checkService.ConnectRemoteApi(new ConnectRemoteApiInput
            {
                InnerCode = _appSetting.InnerCode,
            });
        }
    }

请先安装Quartz.AspNetCore nuget包,我使用的是最新的版本3.4.0,Execute方法默认是异步的,如果你的业务没有异步,可以使用Task.CompletedTask。

2.Job和Trigger绑定

作业已经实现,何时进行触发呢,Quartz.NET提供了一个trigger的概念。job和trigger进行绑定,Quartz既可以调度我们的job了。触发器和job的绑定,可以通过代码的方式,也可以通过xml形式(可以通过设置参数ScanInterval支持定期去扫描最新的变动),以下代码演示代码配置的两种方式进行调度我们的作业CheckRemoteApiJob。

2.1.使用ScheduleJob方法,Job绑定到单个Trigger,代码如下:
代码语言:javascript
复制
builder.Services.Configure<AppSetting>(builder.Configuration.GetSection("AppSetting"));
builder.Services.AddHttpClient();
builder.Services.AddScoped<ICheckService, CheckService>();

builder.Services.AddQuartz(q =>
{
    //支持DI,默认Ijob 实现不支持有参构造函数
    q.UseMicrosoftDependencyInjectionJobFactory();

    q.ScheduleJob<CheckRemoteApiJob>(trigger => trigger
            .WithIdentity("ConnectionRemoteApiTrigger")
            .StartAt(DateBuilder.EvenSecondDate(DateTimeOffset.UtcNow.AddSeconds(7)))
            .WithDailyTimeIntervalSchedule(x => x.WithInterval(builder.Configuration.GetValue<int>("AppSetting:CheckRemoteApiJobIntervalMinute"), IntervalUnit.Minute))
            .WithDescription("定时访问远程接口")
        );

});
builder.Services.AddQuartzServer(options =>
{
    // when shutting down we want jobs to complete gracefully
    options.WaitForJobsToComplete = true;
});

builder.Services.AddTransient<CheckRemoteApiJob>();

调用ScheduleJob方法,job默认只能绑定一个trigger。

运行代码,在控制台查看,每隔1分钟输出如下

2.2.job可以绑定到多个Trigger
代码语言:javascript
复制
builder.Services.AddQuartz(q =>
{
    //支持DI,默认Ijob 实现不支持有参构造函数
    q.UseMicrosoftDependencyInjectionJobFactory();
    //------sample
    //q.ScheduleJob<CheckRemoteApiJob>(trigger => trigger
    //        .WithIdentity("ConnectionRemoteApiTrigger")
    //        .StartAt(DateBuilder.EvenSecondDate(DateTimeOffset.UtcNow.AddSeconds(7)))
    //        .WithDailyTimeIntervalSchedule(x => x.WithInterval(builder.Configuration.GetValue<int>("AppSetting:CheckRemoteApiJobIntervalMinute"), IntervalUnit.Minute))
    //        .WithDescription("定时访问远程接口")
    //    );


    //---------cron

    var jobKey = new JobKey("ConnectionRemoteApi job", "ConnectionRemoteApi group");

    q.AddJob<CheckRemoteApiJob>(jobKey, j => {
        j.WithDescription("定时访问远程接口job");
    });


    q.AddTrigger(t => t
           .WithIdentity("ConnectionRemoteApi Cron Trigger")
           .ForJob(jobKey)
           .StartAt(DateBuilder.EvenSecondDate(DateTimeOffset.UtcNow.AddSeconds(3)))
           .WithCronSchedule(builder.Configuration.GetValue<string>("AppSetting:CheckRemoteApiJobCron"))
           .WithDescription("定时访问远程接口trigger")
       );

});

如果不想使用cron表达式,也可以使用方法 WithSimpleSchedule替换 如:

代码语言:javascript
复制
WithSimpleSchedule(x=> x.WithInterval(TimeSpan.FromMinutes(builder.Configuration.GetValue<int>"AppSetting:CheckRemoteApiJobIntervalMinute"))).RepeatForever())

再次运行代码,跟上面的输出是一样的。

参考官网:https://www.quartz-scheduler.net/

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2022-04-17,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 dotNET知音 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1.准备工作
  • 实现Ijob接口
    • 2.1.使用ScheduleJob方法,Job绑定到单个Trigger,代码如下:
      • 2.2.job可以绑定到多个Trigger
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档