集成了这个分布式任务调度平台,真的很爽~~

前言

在项目开发过程中,后台任务很多场景都少不了,比如:大量数据处理或分析、定时同步数据、大量数据的异步导出、消息补偿等等,在.NET中Quartz-NET、Hangfire是很多小伙伴的首要选择,但如果要弄一个通用、灵活配置的调度平台,还得花很多时间进行封装;当然也有一些小伙伴造了轮子,用起来也还不错;但这里想给小伙伴们介绍XXL-JOB分布式任务调度平台,这是和朋友不经意的聊天中提到的,在Java中用的很爽,于是就想看看能不能在.NET项目中集成起来。

正文

1. XXL-JOB简介

1.1 概述

XXL-JOB是一个分布式任务调度平台,其核心设计目标是开发迅速、学习简单、轻量级、易扩展。现已开放源代码并接入多家公司线上产品线,开箱即用;

这个项目是用Java开发的,所以刚开始还怀疑会不会不能集成.NET项目,第一反应就先去Nuget包中找找有没有现成的轮子,果然有小伙伴已经在用了,于是我肯定得安排上。

这个项目的文档真的是超详细,我就不在这里浪费大家时间,大家可以直接看gitee或github上的文档,而且这个项目在码云和github都很火的。地址如下:

1.2 经典功能介绍

先不急着演示,给小伙伴先说说几个比较吸引人的功能,如下(当然不限于此):

  • 简洁好看的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综艺圈”,和我一起学习吧。

页面下部广告