在项目开发过程中,后台任务很多场景都少不了,比如:大量数据处理或分析、定时同步数据、大量数据的异步导出、消息补偿等等,在.NET中Quartz-NET、Hangfire是很多小伙伴的首要选择,但如果要弄一个通用、灵活配置的调度平台,还得花很多时间进行封装;当然也有一些小伙伴造了轮子,用起来也还不错;但这里想给小伙伴们介绍XXL-JOB分布式任务调度平台,这是和朋友不经意的聊天中提到的,在Java中用的很爽,于是就想看看能不能在.NET项目中集成起来。
正文 1. XXL-JOB简介 1.1 概述XXL-JOB是一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用;
这个项目是用Java开发的,所以刚开始还怀疑会不会不能集成.NET项目,第一反应就先去Nuget包中找找有没有现成的轮子,果然有小伙伴已经在用了,于是我肯定得安排上。
这个项目的文档真的是超详细,我就不在这里浪费大家时间,大家可以直接看gitee或github上的文档,而且这个项目在码云和github都很火的。地址如下:
-
gitee:https://gitee.com/xuxueli0323/xxl-job
-
github:https://github.com/xuxueli/xxl-job
先不急着演示,给小伙伴先说说几个比较吸引人的功能,如下(当然不限于此):
-
简洁好看的Web界面:操作简单,轻松管理任务;
-
注册中心: 执行器会周期性自动注册任务, 调度中心将会自动发现注册的任务并触发执行。同时,也支持手动录入执行器地址;
-
集群和分布式很给力:调度中心和任务执行器可以进行集群部署,实现高可用;
-
健康检查:保证调度的高可用;
-
一致性: “调度中心”通过DB锁保证集群分布式调度的一致性, 一次任务调度只会触发一次执行;
-
分片广播任务:当任务执行器集群部署时,比如需要处理大量数据时,可以通过对应参数,将数据拆分给不同的任务执行器处理,提高效率;
-
邮件报警:任务失败时支持邮件报警,支持配置多邮件地址群发报警邮件;
-
用户/权限管理:支持在线管理系统用户,存在管理员、普通用户两种角色
上面只是列举了一小部分功能,具体详细可以看文档,如果大家对调度中心和执行器不太明白,可以看看XXL-JOB的架构图:
其中我们只负责编写执行器中的JobHandler(任务处理逻辑)即可,其他的框架已经帮忙搞定了。
2 环境安装 2.1 先安装数据库及初始化数据库要求是MySQL5.7+ ,这里采用的是MySQL5.7,安装数据库的教程就不一一截图了,菜鸟教程很详细(https://www.runoob.com/docker/docker-install-mysql.html)。
需要注意的是,MySql数据安装完成之后,一定要配置允许远程连接。
数据库安装完成之后,连接到MySQL服务器(用工具或命令行都行),然后进行XXL-JOB数据库的初始化,其实就是执行对应的脚本创建对应的表,插入默认用户,脚本位置如下:
https://gitee.com/xuxueli0323/xxl-job/tree/master/doc/db
2.2 Docker 部署XXL-JOB调度中心关于XXL-JOB的部署可以用下载源码进行部署,配置比较灵活;也可以用Docker的方式进行部署,比较方便。这里演示就用Docker的方式,执行以下命令即可(前提是有Docker的环境,如果对Docker不熟的,我之前分享的有相关文章《Docker系列》):
docker run -e PARAMS="--spring.datasource.url=jdbc:mysql://172.29.211.138:3306/xxl_job?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&serverTimezone=Asia/Shanghai --spring.datasource.username=root --spring.datasource.password=123456" -p 5000:8080 -v /tmp:/data/applogs --name xxl-job-admin -d xuxueli/xxl-job-admin:2.3.0
- -e PARAMS :指定参数,这里主要是配置数据库连接、字符集、时区等;
- -p 5000:8080 : 端口映射
- -v 数据卷挂载
- --name :设置容器名字
- -d : 容器运行方式为后台运行
容器启动之后,就可以访问界面了(如果是云服务器,记得要安全实例和防火墙都要放开端口,之前的文章中有说到)。
输入默认用户名和密码: admin/123456
进入到主界面,代表调度中心已经搭建好了:
调度中心搞定之后,接下来就是业务逻辑编写啦。
3 .NET项目集成 3.1 安装Nuget包在.NET项目中,需要一个能集成到XXL-JOB的执行器,这里已经有些小伙伴造好轮子了,其中DotXxlJob.Core这个相对还不错,对应开源的地址如下:
https://github.com/NanoFabricFX/DotXxlJob。
安装这个包之后,按要求准备一个中间件和对应配置信息即可,这里文档都说的挺详细。对了,这里创建的还是一个API项目。
3.2 按要求准备一个中间件并进行注册public class XxlJobExecutorMiddleware
{
private readonly IServiceProvider _provider;
private readonly RequestDelegate _next;
private readonly XxlRestfulServiceHandler _rpcService;
public XxlJobExecutorMiddleware(IServiceProvider provider, RequestDelegate next)
{
this._provider = provider;
this._next = next;
this._rpcService = _provider.GetRequiredService<XxlRestfulServiceHandler>();
}
public async Task Invoke(HttpContext context)
{
string contentType = context.Request.ContentType;
// 处理Post类型的请求
if ("POST".Equals(context.Request.Method, StringComparison.OrdinalIgnoreCase)
&& !string.IsNullOrEmpty(contentType)
&& contentType.ToLower().StartsWith("application/json"))
{
await _rpcService.HandlerAsync(context.Request, context.Response);
return;
}
await _next.Invoke(context);
}
}
为了方便注册中间件,再写一个扩展方法,如下:
public static class ApplicationBuilderExtensions
{
public static IApplicationBuilder UseXxlJobExecutor(this IApplicationBuilder @this)
{
return @this.UseMiddleware<XxlJobExecutorMiddleware>();
}
}
接下来就是在Startup.cs文件中进行相关服务的注册及注册中间件,如下:
在配置文件appsettings.json中增加配置信息,如下:
{
"Logging": {
"LogLevel": {
"Default": "Information",
"Microsoft": "Warning",
"Microsoft.Hosting.Lifetime": "Information"
}
},
"xxlJob": {
"adminAddresses": "http://112.xxx.xxx.127:5000/xxl-job-admin",
"appName": "xxl-job-executor-dotnet",
"specialBindAddress": "172.29.211.138",
"port": 8888,
"autoRegistry": true,
"accessToken": "",
"logRetentionDays": 20
},
"AllowedHosts": "*"
}
- adminAddresses:调度中心的地址,多个地址可以用逗号隔开;
- appName:执行器名称,后续会在调度中心展示,如果是在调度中心手动录入时,执行器名称要一致;
- specialBindAddress:自动注册时提交到调度中心的IP地址,为空会自动获取内网IP地址。可以理解为业务站点部署的IP地址;
- port:自动注册时提交到调度中心的端口,可以理解为业务站点部署的端口;
- autoRegistry:是否自动注册
- accessToken:如果需要accessToken做认证就填,不需要就不用填
- logPath:日志保存路径,不写就保存到程序运行当前路径
- logRetentionDays:日志保留天数
接下来就可以开始写业务代码了。
3.3 编写业务代码注:一定要标识上特性,指定名称,这个调度中心新增任务时会用到。
编写完之后,将其进行服务注册:
将程序发布到云服务器上,因为我本地电脑不能被访问,保证调度中心和业务站点正常互相访问即可。
因为新买的Linux环境没有安装运行时环境,这里就用独立模式进行部署(.NET的两种部署模式,了解一下这篇文章有分享过),如下:
3.4 调度中心中配置任务调度先去执行器管理进行执行器维护,如果是自动注册,这里会自动多出相关记录,也可以进行手工录入,但要确保AppName和业务程序指定的一致。
详细信息如下:
确定有执行器之后,就可以添加任务调度了:
3.5 看效果这样就可以在任务管理界面进行控制了,如下:
然后在调度中心的任务管理模块,针对新添加的任务点击执行测试一下,没问题再点击启动看看运行效果,如下:
调度正常,关于Cron表达式的方式就不在这介绍了,就留给小伙伴们自己试试吧。
XXL-JOB的功能使用就先介绍这么多吧,其他策略方式小伙伴亲自体验一下,然后才能针对不同的业务使用不同的策略。
演示代码地址:https://gitee.com/CodeZoe/dot-net-core-study-demo/tree/main/xxl-jobDemo
总结这个分布式调度平台是不是很给力,这里只是演示了怎么集成使用,其实里面的功能还有很多,基本上简单的配置就可以搞定;而且他的文档真的很详细,所以不明白的基本上查文档都能弄清楚。
有了这个平台,根本不用愁再去封装一个调度平台,一心只关注业务代码开发就行了。而且这个平台是跨语言的,提供Java、Python、PHP……等十来种任务模式,而且根据他文档登记得知,很多大公司都在用。
关注“Code综艺圈”,和我一起学习吧。