概述
ScheduleMaster 是一个开源的分布式任务调度系统, 它基于 ASP.NET Core 平台构建, 支持跨平台多节点部署运行.
它的项目主页在这里:
https://github.com/hey-hoho/ScheduleMasterCore
关于它的简单介绍可以看这里:
https://www.cnblogs.com/hohoa/p/12162581.html
本地部署
使用前请准备好所需环境: Visual Studio 2019,.Net Core3.0 SDK,MySQL 5.7,CentOS(可选),Docker(可选).
下载源码到本地, 然后用 VS2019 打开解决方案并编译通过.
打开项目 Hos.ScheduleMaster.web 根目录下的 appsettings.JSON 文件, 先修改 MySQL 数据库连接字符串以保证数据库正常访问, 再找到 NodeSetting 节点, 修改 IP 字段为 master 将要部署的 ip 地址 (master 端口为 30000 不用修改), 在项目上右击选择发布..., 发布到本地文件夹.
打开项目 Hos.ScheduleMaster.QuartzHost 根目录下的 appsettings.JSON 文件, 同样先修改 MySQL 连接字符串, 再找到 NodeSetting 节点, 设置 worker 的名称 IdentityName, 修改 IP 字段为将要部署的 ip 地址, Port 字段为要监听的地址 (推荐为 30001), 在项目上右击选择发布..., 发布到本地文件夹. 如果要新增 worker, 按同样方式配置 IdentityName,IP,Port 即可, worker 在启动后会把自己的信息注入到数据库中, 在 master 中可以看到.
其他发布方式亦可. 下面以运行 2 个 worker 节点为例:
在 Windows 中运行
找到 master 的发布目录, 执行命令
dotnet Hos.ScheduleMaster.Web.dll
启动程序, 首次启动会自动迁移生成数据库结构并初始化种子数据, 不需要执行脚本创建数据库, 打开浏览器输入 ip 和端口访问即可 (初始用户名 admin, 密码
111111
).
找到 worker 的发布目录, 执行命令
dotnet Hos.ScheduleMaster.QuartzHost.dll --urls http://*:30001
启动程序, 打开浏览器输入 ip 和端口会看到一个欢迎页面, 表示 worker 已启动成功.
修改 worker 下的 appsettings.JSON 文件为 worker2 的配置 (如果发布前已经修改可跳过), 执行命令
dotnet Hos.ScheduleMaster.QuartzHost.dll --urls http://*:30002
启动程序.
登录到 master 中, 可以看到节点管理菜单下各节点的运行状态.
在 Linux(CentOS) 中运行
运行前请确保机器已经安装好. Net Core3.0 运行时环境.
把发布文件复制到 CentOS 中, 操作步骤同 Windows.
在 Docker 中运行
在 master 的发布目录中执行
docker build -t ms_master .
命令生成 master 镜像, 再执行
docker run -d -p 30000:30000 --name="mymaster" ms_master
运行容器.
在 worker 的发布目录中执行
docker build -t ms_worker .
命令生成 worker 镜像, 再执行
docker run -d -p 30001:30001 --name="myworker1" ms_worker
运行容器启动 worker1, 在执行
docker run -d -p 30002:30001 --name="myworker2" ms_worker
运行容器启动 worker2.
执行 docker ps 查看各容器运行状态.
接入一个任务
我们看一下如何编写业务代码以及怎么创建和启动一个任务.
编写业务代码
框架提供了统一的接入口, 可以使用如下 3 种方式:
编译项目后手动添加引用程序集文件 Hos.ScheduleMaster.Base.dll.
在 nuget 中搜索 ScheduleMaster 直接安装到项目中.
在命令行中使用 dotnet add package ScheduleMaster 或程序包管理控制台中使用 install-package ScheduleMaster 安装.
然后新建一个业务类, 集成自 Hos.ScheduleMaster.Base.TaskBase, 实现它的抽象方法 Run 就可以了, 这个方法就是任务的入口.
下面是项目中最简单的一个 Demo:
- using System;
- using Hos.ScheduleMaster.Base;
- namespace Hos.ScheduleMaster.Demo
- {
- public class Simple : TaskBase
- {
- public override void Run(TaskContext context)
- {
- context.WriteLog($"当前时间是:{DateTime.Now}");
- }
- }
- }
据有些朋友反馈, 希望能加入单纯的 http 调度功能, 这个将会作为重点功能在后面开发.
使用控制台创建任务
我以内置到系统中的 demo 任务为例子. 首先登录到 master 控制台中进入到任务列表页面, 选择创建任务, 填写好配置信息:
如果需要指定参数, 可以按如下方法设置:
在代码中使用如下代码读取自定义参数:
- public override void Run(TaskContext context)
- {
- context.GetArgument<string>("param1");
- context.GetArgument<int>("param2");
- }
如果需要指定监护人, 可以按如下方法设置:
如果在执行完成后要自动触发其他的任务, 可以通过如下方式设置 (拖拽选择):
前面的任务可以通过如下代码把结果传给后面的任务:
- public override void Run(TaskContext context)
- {
- context.Result = new { success = true, message = "后面的兄弟大家好~" };
- }
后面的任务获取前面的结果:
- public override void Run(TaskContext context)
- {
- object pr=context.PreviousResult;
- }
这里重点说一下程序包的问题, 因为程序包是以程序集名称来打包并管理的, 如果多个任务属于同一个程序集中, 那么就不需要每个任务都重复上传程序包, 同名的程序包重复上传会把已有的覆盖掉. 这样子的话程序集的版本问题就要特别注意下, 要避免同一程序包里的任务互相影响.
如果你想跑一个示例看看效果, 可以按上面截图中配置基础信息即可, 不需要再上传程序包.
使用 API 创建任务
除了使用控制台页面操作任务, 系统还提供了几个简单的 WebApi 来操作, 目前包括创建任务, 查询任务详情, 查询任务列表.
下面主要介绍创建任务 API, 接口定义如下:
访问地址: http://localhost:30000/API/task/create
请求类型: POST
主要参数:
参数名称 | 参数类型 | 是否必填 | 说明 |
---|---|---|---|
Title | string | 是 | 任务名称 |
RunLoop | bool | 是 | 是否按周期执行 |
CronExpression | string | 否 | cron 表达式,如果 RunLoop 为 true 则必填 |
AssemblyName | string | 是 | 程序集名称 |
ClassName | string | 是 | 执行类名称,包含完整命名空间 |
StartDate | DateTime | 是 | 任务开始时间 |
EndDate | DateTime | 否 | 任务停止时间,为空表示不限停止时间 |
Remark | string | 否 | 任务描述说明 |
CreateUserName | string | 是 | 创建人用户名 |
Keepers | List<int> | 否 | 监护人 id |
Params | List<ScheduleParam> | 否 | 自定义参数列表 |
对接流程:
在控制台中创建好专用的 API 对接用户账号.
使用对接账号的用户名设置为 http header 中的 ms_auth_user 值.
使用加密过的秘钥设置为 http header 中的 ms_auth_secret 值, 加密规则: 按
{用户名}{密码}{用户名}
的格式拼接, 然后用 32 位的 MD5 算法进行加密, 最后转换成小写字符串得到秘钥.
使用 form 格式发起 http 调用, 如果非法用户会返回 401-Unauthorized.
接口验签这块设计的比较简陋, 因为考虑到这个场景使用的不多而且基本是内部系统调用, 所以只做了简单验证. 具体实现代码在 Hos.ScheduleMaster.Web.Filters.AccessControlFilter.
创建成功会返回任务 id.
要提一下的是, 使用 API 创建任务的方式不支持上传程序包, 所以在任务需要启动时要确保程序包已通过其他方式上传, 否则会启动失败.
启动流程
日志跟踪
在设计上, 我把任务的每次运行定义为一个 Trace 并为之分配一个 traceid, 这样的话就能对产生的日志进行归类, 区分哪一条是哪次运行产生的.
写入日志的方法为:
- public override void Run(TaskContext context)
- {
- context.WriteLog("xxxxxxx");
- context.WriteError(exception);
- }
页面上在这里查看:
单击左边的运行记录可以看到与之关联的详细日志信息:
好了, 这篇先就这么多~
结尾
来源: https://www.cnblogs.com/hohoa/p/12197518.html