.NET Core 环境下 ScheduleMaster 分布式调度系统的架构解析与落地指南
系统架构简介
ScheduleMaster 是一个构建于 AspNetCore 之上的开源项目,旨在提供企业级的分布式任务调度能力。该系统采用 Master-Worker 分离架构,支持跨操作系统环境的多节点集群部署,能够有效解决复杂业务场景下的定时任务管理问题。
项目代码托管于公开仓库,开发者可参考相关文档进行二次开发或集成。
运行环境准备与初始化
在正式部署之前,需确保基础软件栈满足要求,包括 Visual Studio 2019(用于开发编译)、.NET Core 3.0 SDK、MySQL 5.7 数据库服务器。对于容器化部署,Docker 是可选但推荐的组件;若选择物理机 Linux 部署,CentOS 系统是常见的选择。
首先获取源代码并加载至 IDE 中进行编译验证。配置的核心在于两个关键服务的配置文件:
- 主控服务 (Web):位于
Hos.ScheduleMaster.Web目录下,需在appsettings.json中配置 MySQL 连接串,并在NodeSetting中指定 Master 节点的 IP 地址。默认端口占用 30000。 - 执行服务 (QuartzHost):位于
Hos.ScheduleMaster.QuartzHost目录下,同样配置数据库连接。关键在于设置唯一的节点标识IdentityName,IP 地址及监听端口(建议 30001)。多个 Worker 节点只需保持标识唯一即可,启动后会自动向主控端注册心跳信息。
多环境部署方案
Windows 本地运行
将编译后的 DLL 文件发布到目标文件夹。首次运行时,系统会自动完成数据库表的迁移及种子数据的插入,无需手动执行 SQL 脚本。
- 启动 Master 进程:
dotnet Hos.ScheduleMaster.Web.dll,随后通过浏览器访问对应 IP:30000,使用默认凭证(用户 admin/密码 111111)登录控制台。 - 启动 Worker 进程:
dotnet Hos.ScheduleMaster.QuartzHost.dll --urls http://*:30001。成功启动后会展示欢迎界面。 - 扩容 Worker:修改配置文件中的身份标识,调整端口号后再次执行启动命令。
Linux 与 Docker 容器化
在 CentOS 环境中,确保已安装运行时环境后,操作逻辑与 Windows 类似。若使用 Docker,可通过以下流程快速构建镜像并编排容器:
# 构建主控镜像
docker build -t schedule_master .
docker run -d -p 30000:30000 -mymaster schedule_master
# 构建执行者镜像并启动实例 1
docker build -t schedule_worker .
docker run -d -p 30001:80 -e identity=worker_node_1 -e port=30001 myworker1 schedule_worker
# 启动第二个执行实例以形成集群
docker run -d -p 30002:80 -e identity=worker_node_2 -e port=30002 myworker2 schedule_worker
可通过 docker ps 指令实时核查容器健康状态。
业务任务开发与接入
要实现具体的业务逻辑,首先需要引入核心程序集。推荐通过 NuGet 包管理器安装 ScheduleMaster 组件。业务代码需继承自基类,并实现标准执行接口。
示例代码重构
以下展示了一个经过优化的任务实现示例,演示了如何记录上下文日志:
using System;
using Hos.ScheduleMaster.Base;
namespace Enterprise.JobHandlers
{
/// <summary>
/// 定期数据清洗任务
/// </summary>
public class DataCleaningJob : TaskBase
{
public override void Run(TaskContext executionContext)
{
var currentTime = DateTime.Now.ToLocalTime();
executionContext.WriteLog($"【开始处理】任务触发时间戳:{currentTime}");
// 在此处编写具体业务逻辑...
}
}
}
注意:由于任务是以程序集(Assembly)维度打包的,若同一程序集包含多个任务,重复上传会覆盖旧版本。因此在进行迭代更新时,务必注意版本兼容性,防止影响同组任务。
任务管理与调度策略
系统提供了可视化的 Web 控制台来管理作业生命周期。
作业创建与参数传递
在控制台的"任务列表"页面新建作业时,需填写 Cron 表达式定义调度周期(若开启周期模式)。对于需要透传参数的场景,可在配置面板中绑定键值对:
代码内部通过上下文对象读取这些动态参数:
public override void Run(TaskContext ctx)
{
string region = ctx.GetArgument<string>("regionCode");
int threshold = ctx.GetArgument<int>("limitValue");
}
任务依赖链
支持串行执行机制。上游任务的产出结果可以通过 Result 属性传递给下游:
// 上游任务
ctx.Result = new { status = true, payload = "批次数据 ID: #10086" };
// 下游任务
var upstreamOutput = ctx.PreviousResult;
if (upstreamOutput != null) { ... }
RESTful API 集成
除了 GUI 操作,系统开放了 HTTP 接口供第三方系统调用。以创建设置为例:
- Endpoint:
/api/task/create(POST) - 鉴权机制: 需要在 Header 中携带
ms_auth_user和加密后的ms_auth_secret。
密钥生成算法较为特定:将"用户名 + 密码 + 用户名"拼接后计算 32 位 MD5 并转为小写。调用失败通常返回 401 状态码。注意 API 创建任务不包含程序包上传功能,需提前确保程序集已就绪。
| 字段名 | 类型 | 必选 | 含义 |
|---|---|---|---|
| Title | string | 是 | 作业标题 |
| CronExpression | string | 否 | 调度规则字符串 |
| ClassName | string | 是 | 完整类名含命名空间 |
| CreateUserName | string | 是 | 创建人标识 |
全链路日志追踪
为了便于故障排查,系统设计了基于 TraceID 的日志追踪体系。每次任务触发均会被视为一次独立的执行轨迹(Trace)。在代码层面向上下文写入日志:
public override void Run(TaskContext ctx)
{
try
{
// 正常业务日志
ctx.WriteLog("数据同步处理中...");
}
catch (Exception ex)
{
// 异常堆栈记录
ctx.WriteError(ex);
}
}
在管理后台,用户可以通过查看执行记录详情页,根据 TraceID 聚合所有相关日志,从而精确定位到某一次调度的具体输入输出及中间状态:
