Quartz.Net源码Example之Quartz.Examples.AspNetCore
Quartz.Examples.AspNetCore
.NetCore的Web系统,后台主要执行多个触发器任务,前台展示所有触发器信息和正在执行的作业的相关信息,还可以通过访问health-UI来查看目前系统健康状态
launchSettings.json
{
"profiles": {
"Quartz.Examples.AspNetCore": {
"commandName": "Project",
// 自动打开浏览器
"launchBrowser": true,
// 默认的链接地址
"applicationUrl": "http://localhost:5000",
"environmentVariables": {
// 开发模式
"ASPNETCORE_ENVIRONMENT": "Development"
}
}
}
}
appsettings.json
Loggin配置,cron设置,路由设置
quartz_jobs.config
触发器和作业的xml配置
Startup
创建Serilog日志
public Startup(IConfiguration configuration)
{
Log.Logger = new LoggerConfiguration()
// 从默认的日志组件中填充事件信息(使用默认配置)
.Enrich.FromLogContext()
// 写入到控制器中
.WriteTo.Console()
// 创建日志
.CreateLogger();
// 赋值
Configuration = configuration;
}
public IConfiguration Configuration { get; }
// 向容器中添加日志
services.AddLogging(loggingBuilder =>
{
loggingBuilder.ClearProviders();
loggingBuilder.AddSerilog(dispose: true);
});
OpenTelemetry
通过标准化不同的应用程序和框架如何收集和发出可观察性遥测数据,用于管理观测类的数据。
- 可观察性遥测(分布式跟踪、指标等)的供应商中立规范
- 实现用于检测的公共接口的API
- 应用程序使用SDK为插件作者配置工具和接口以编写导出器
- 使你能够将数据发送到你选择的遥测后端的导出器
OpenTelemetry搭配Zipkin来追踪ASP.NET Core服务之间的WebAPI和gRPC请求,Zipkin官网地址
OpenTelemetry搭配Uber的分布式跟踪系统Jaeger来监视系统
// 添加观测数据工具
services.AddOpenTelemetryTracing(builder =>
{
builder
// 启用Quartz.NET作业自动数据收集功能
.AddQuartzInstrumentation()
// 使用Zipkin来追踪数据请求
.AddZipkinExporter(o =>
{
o.Endpoint = new Uri("http://localhost:9411/api/v2/spans");
})
// 添加Jaeger监听
.AddJaegerExporter(o =>
{
// these are the defaults
o.AgentHost = "localhost";
o.AgentPort = 6831;
});
});
services.AddRazorPages()
Razor Pages
功能:cshtml视图模板- 身分验证服务
Data Annotation
- 支持Attribute
资料检核及IValidateObject
Cache Tag Helper
AddMvcCore()
核心服务
Quartz.NET相关代码
// 配置
services.Configure<QuartzOptions>(options =>
{
// 忽略重复项,默认为false
options.Scheduling.IgnoreDuplicates = true;
// 替换现有配置信息和数据信息,默认为true
options.Scheduling.OverWriteExistingData = true;
});
// 添加调度配置
services.AddQuartz(q =>
{
// 唯一表示
q.SchedulerId = "Scheduler-Core";
// 程序关闭时中断作业
q.InterruptJobsOnShutdown = true;
// 程序关闭时等待作业关闭
q.InterruptJobsOnShutdownWithWait = true;
// 并发作业数,默认是1
q.MaxBatchSize = 5;
// -- 一下是默认方法
// 默认使用Microsoft的依赖注入
q.UseMicrosoftDependencyInjectionJobFactory();
// 使用默认的类型加载器
q.UseSimpleTypeLoader();
// 使用默认的内存存储
q.UseInMemoryStore();
// 默认的线程池,最大线程数为10
q.UseDefaultThreadPool(maxConcurrency: 10);
// 自动中断长时间运行的作业
q.UseJobAutoInterrupt(options =>
{
// 默认最长时间为5分钟
options.DefaultMaxRunTime = TimeSpan.FromMinutes(5);
});
// 使用时间转换器,主要用于不同系统之间的转换
q.UseTimeZoneConverter(); // 添加监听
q.AddSchedulerListener<SampleSchedulerListener>();
q.AddJobListener<SampleJobListener>(GroupMatcher<JobKey>.GroupEquals(jobKey.Group));
q.AddTriggerListener<SampleTriggerListener>();
}
// 每次都创建一个不同的ExampleJob实例 (AddTransient)
services.AddTransient<ExampleJob>(); // 添加SecondSampleJobListener监听(AddSingleton:单例模式)
services.AddSingleton<IJobListener, SecondSampleJobListener>();
services.AddSingleton<ITriggerListener>(serviceProvider =>
{
// 添加SecondSampleTriggerListener触发器
var logger = serviceProvider.GetRequiredService<ILogger<SecondSampleTriggerListener>>();
return new SecondSampleTriggerListener(logger, "Example value");
});
// 将appsettings.json的配置信息映射到SampleOptions的实例中
services.Configure<SampleOptions>(Configuration.GetSection("Sample"));
// 增加Quzrtz.NET的配置项
services.AddOptions<QuartzOptions>()
.Configure<IOptions<SampleOptions>>((options, dep) =>
{
if (!string.IsNullOrWhiteSpace(dep.Value.CronSchedule))
{
var jobKey = new JobKey("options-custom-job", "custom");
options.AddJob<ExampleJob>(j => j.WithIdentity(jobKey));
options.AddTrigger(trigger => trigger
.WithIdentity("options-custom-trigger", "custom")
.ForJob(jobKey)
.WithCronSchedule(dep.Value.CronSchedule));
}
});
// 添加Quartz.NET的服务
services.AddQuartzServer(options =>
{
// 当程序关闭时需要等待作业完成
options.WaitForJobsToComplete = true;
});
AddHealthChecksUI
添加健康检查的页面
精简方式,访问/health判断健康状态
/*
健康等级
Healthy 健康
Unhealthy 不良
Degraded 降级
*/
public void ConfigureServices(IServiceCollection services){
service.AddHealthchecks();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
//可以通过访问/health链接来查看健康等级
app.MapHealthChecks("/health");
}UI页面-Quartz.NET方式
// appsettings.json中
// 健康检测的配置信息
"HealthChecksUI": {
// 可以同时监控多个健康检查API
"HealthChecks": [
{
"Name": "localhost",
"Uri": "/healthz"
}
],
// 当API的健康状态改变时,向指定Uri发送告警数据
"Webhooks": []
} public void ConfigureServices(IServiceCollection services){
// 添加健康检测页面,并将数据存放到内存中
services
.AddHealthChecksUI()
.AddInMemoryStorage();
}
public void Configure(IApplicationBuilder app, IWebHostEnvironment env)
{
app.UseEndpoints(endpoints =>
{
// 配置路由
endpoints.MapRazorPages();
// 健康检测的url链接
endpoints.MapHealthChecks("healthz", new HealthCheckOptions
{
Predicate = _ => true,
// 返回json格式健康检查数据
ResponseWriter = UIResponseWriter.WriteHealthCheckUIResponse
});
// 添加健康检测页面到路由中,默认为healthchecks-ui
endpoints.MapHealthChecksUI();
});
}
Configure(IApplicationBuilder app, IWebHostEnvironment env)
配置Http request的管道
- app.UseHsts() 将 HTTP 严格传输安全协议 (HSTS) 标头发送到客户端
- app.UseStaticFiles(); 使用静态资源
- app.UseRouting() 使用路由
SampleJobListener
监听中添加logger
// 初始化请参见:Startup->1.创建Serilog日志
// 实现JobListenerSupport而非IJobListener
public class SampleJobListener : JobListenerSupport
{
//声明一个logger
private readonly ILogger<SampleJobListener> logger; public SampleJobListener(ILogger<SampleJobListener> logger)
{
//赋值
this.logger = logger;
}
public override string Name => "Sample Job Listener";
public override Task JobToBeExecuted(IJobExecutionContext context, CancellationToken cancellationToken = default)
{
// 使用
logger.LogInformation("The job is about to be executed, prepare yourself!");
return Task.CompletedTask;
}
} // 程序中使用logger的监听
services.AddQuartz(q =>
// 调用监听类-只给jobkey.Group这个群组的创建此监听
q.AddJobListener<SampleJobListener>(GroupMatcher<JobKey>.GroupEquals(jobKey.Group));
);
wwwroot
静态资源文件
通过后台UseStaticFiles()方法引入静态变量
Pages部分---Razor页面
自动生成部分
// View 加上@符就代表是c#相关代码
@page
@model Quartz.Examples.AspNetCore.Pages.Index1Model
@{
} // ViewModel
namespace Quartz.Examples.AspNetCore.Pages
{
public class Index1Model : PageModel
{
// 页面加载时调用
public void OnGet()
{
}
}
}
2.Quartz.NET中的Razor
View
@page
@model IndexModel
@{
// Html中的title标签值
ViewData["Title"] = "Home page";
}
<div class="text-center">
<h1 class="display-4">Scheduled Triggers</h1>
// 调用Control中的Model的Triggers变量
@foreach (var trigger in Model.Triggers)
{
// 将触发器的群组和名称放到span标签中
<span>@trigger.Group / @trigger.Name</span>
<br/>
}
<br />
<h1 class="display-4">Currently Executing Jobs</h1>
@foreach (var job in Model.CurrentlyExecutingJobs)
{
<span>@job.JobDetail.Key.Group / @job.JobDetail.Key.Name - triggered by @job.Trigger.Key.Group / @job.Trigger.Key.Name</span>
<br/>
}
<br />
<h1 class="display-4">Health Status</h1>
<a href="/healthchecks-ui">Open health checks UI</a>
</div>
ViewModel
public class IndexModel : PageModel
{
// 引入Logging
private readonly ILogger<IndexModel> _logger;
// 声明一个调度工厂类
private readonly ISchedulerFactory schedulerFactory; // 在服务启动前需要将需要的类进行配置,配置完成后系统会通过接口类获得单例的相关实现类,如java的spring
public IndexModel(
ILogger<IndexModel> logger,
ISchedulerFactory schedulerFactory)
{
_logger = logger;
this.schedulerFactory = schedulerFactory;
}
// 只读的集合,赋值为空集合
public IReadOnlyCollection<TriggerKey> Triggers { get; set; } = Array.Empty<TriggerKey>();
public IReadOnlyCollection<IJobExecutionContext> CurrentlyExecutingJobs { get; set; } = Array.Empty<IJobExecutionContext>(); public async Task OnGet()
{
// 等待获取调取实例
var scheduler = await schedulerFactory.GetScheduler();
//获得所有的触发器
Triggers = await scheduler.GetTriggerKeys(GroupMatcher<TriggerKey>.AnyGroup());
// 获得所有在执行的调度作业上下文
CurrentlyExecutingJobs = await scheduler.GetCurrentlyExecutingJobs();
}
}
Quartz.Net源码Example之Quartz.Examples.AspNetCore的更多相关文章
- Pytorch学习之源码理解:pytorch/examples/mnists
Pytorch学习之源码理解:pytorch/examples/mnists from __future__ import print_function import argparse import ...
- cache2go源码最后一讲 - examples
先看一下我们讲到哪里了: cache2go的源码前面我们已经讲完了cacheitem和cachetable的实现,今天cahce和examples会一起讲完~ 1.cache.go源码 ...
- ASP.NET Core 源码阅读笔记(5) ---Microsoft.AspNetCore.Routing路由
这篇随笔讲讲路由功能,主要内容在项目Microsoft.AspNetCore.Routing中,可以在GitHub上找到,Routing项目地址. 路由功能是大家都很熟悉的功能,使用起来也十分简单,从 ...
- ASP.NET Core 源码阅读笔记(3) ---Microsoft.AspNetCore.Hosting
有关Hosting的基础知识 Hosting是一个非常重要,但又很难翻译成中文的概念.翻译成:寄宿,大概能勉强地传达它的意思.我们知道,有一些病毒离开了活体之后就会死亡,我们把那些活体称为病毒的宿主. ...
- java ssm 后台框架平台 项目源码 websocket IM quartz springmvc
A代码编辑器,在线模版编辑,仿开发工具编辑器,pdf在线预览,文件转换编码B 集成代码生成器 [正反双向](单表.主表.明细表.树形表,快速开发利器)+快速表单构建器freemaker模版技术 ,0个 ...
- quartz(7)-源码分析
定时器启动 上图通过spring加载quartz <bean id="scheduler" class="org.springframework.schedulin ...
- Quartz.Net系列(三):解读Quartz.Net源码领略设计模式在其中的应用
1.Builder(建造者)模式 JobBuilder DateBuilder 其他的Builder(TriggerBuilder.SchedulerBuilder等) 2.抽象工厂模式 ISch ...
- quartz集群调度机制调研及源码分析---转载
quartz2.2.1集群调度机制调研及源码分析引言quartz集群架构调度器实例化调度过程触发器的获取触发trigger:Job执行过程:总结:附: 引言 quratz是目前最为成熟,使用最广泛的j ...
- 定时组件quartz系列<三>quartz调度机制调研及源码分析
quartz2.2.1集群调度机制调研及源码分析引言quartz集群架构调度器实例化调度过程触发器的获取触发trigger:Job执行过程:总结:附: 引言 quratz是目前最为成熟,使用最广泛的j ...
- anki_vector SDK源码解析(教程)
一:最近anki vector robot开放了Python SDK,我听到的第一时间就赶快上网查了查,先抛几个官网重要链接吧: Python编程API手册及环境搭建等: https://sdk-re ...
随机推荐
- 第2-1-2章 传统方式安装FastDFS-附FastDFS常用命令
目录 3 安装配置 3.1 安装GCC 3.2 安装libevent 3.3 安装libfastcommon 3.4 安装FastDFS 3.5 安装fastdfs-nginx-module 3.5 ...
- python uiautomator
电脑连接上一个手机或多个手机, 确保adb已经添加到环境变量中,执行下面的命令会自动安装本库所需要的设备端程序:uiautomator-server .atx-agent.openstf/minica ...
- 1.docker的基本使用
1.简介 Docker 是一个开源的应用容器引擎,让开发者可以打包他们的应用以及依赖包到一个可移植的镜像中,然后发布到任何流行的 Linux或Windows操作系统的机器上,也可以实现虚拟化.容器是完 ...
- Web安全Day1 - SQL注入、漏洞类型
Web安全Day1 - SQL注入.漏洞类型 1. SQL注入 1.1 漏洞简介 1.2 漏洞原理 1.3 漏洞危害 2. SQL漏洞类型 2.1 区分数字和字符串 2.2 内联SQL注入 2.3 报 ...
- 聊聊如何让办公网络直连Kubernetes集群PodIP/ClusterIP/Service DNS等
想象一下,如果您日常使用的研发测试Kubernetes集群,能够有以下效果: 在办公网络下直接访问Pod IP 在办公网络下直接访问Service Cluster IP 在办公网络下直接访问集群内部域 ...
- docker给已存在的容器添加或修改端口映射
简述: 这几天研究了一下docker, 发现建立完一个容器后不能增加端口映射了,因为 docker run -p 有 -p 参数,但是 docker start 没有 -p 参数,让我很苦恼,无奈谷歌 ...
- 第2-4-8章 规则引擎Drools实战(1)-个人所得税计算器
目录 9. Drools实战 9.1 个人所得税计算器 9.1.1 名词解释 9.1.2 计算规则 9.1.2.1 新税制主要有哪些变化? 9.1.2.2 资较高人员本次个税较少,可能到年底扣税增加? ...
- 《吐血整理》高级系列教程-吃透Fiddler抓包教程(35)-Fiddler如何抓取微信小程序的包-下篇
1.简介 通过前边和宏哥的学习,我们了解到Android 7.0 之后增加了对第三方证书的限制,抓包工具(charles.fiddler等)提供的证书都无法通过校验,也就无法抓取HTTPS请求了,对测 ...
- 【终极解决办法】pyinstaller打包exe没有错误,运行exe提示Failed to execute script 'mainlmageWindows' due tounhandled exception: No module named 'docx'
一.通过pyinstaller打包exe可执行文件,由于我的py是多个,所以要先生成spec文件,代码如下: pyi-makespec mainImageWindows.py 此时生产了一个mainI ...
- 写一个flutter程序
这一部分我们写一个简单应用 功能是,为一个创业公司生成建议的公司名称. 用户可以选择和取消选择的名称,保存喜欢的名称. 该代码一次生成十个名称 用户滚动时,生成新一批名称. 着重体验以下几点 Flut ...