Hangfire.HttpJob Agent自动注册机制详解:调度中心与业务执行器如何自动握手
Hangfire.HttpJob Agent自动注册机制详解调度中心与业务执行器如何自动握手【免费下载链接】Hangfire.HttpJobhttpjob for Hangfire,restful api for Hangfire,job调度与业务分离项目地址: https://gitcode.com/gh_mirrors/ha/Hangfire.HttpJobHangfire.HttpJob 是一个把任务调度与业务执行彻底分离的开源项目调度中心Hangfire Server只负责编排任务、下发指令、监控状态而真正的业务代码跑在独立的 Agent 进程里。其中最具特色、也最容易被忽略的正是Hangfire.HttpJob Agent自动注册机制——业务执行器启动后无需任何人工配置就能自动在调度中心报到并通过心跳机制与调度中心完成自动握手。本文用新手也能听懂的方式带你完整拆解这套机制的运行原理与配置方法。1. 先理解整体架构调度中心 Agent 业务执行器 ️传统 Hangfire 任务往往和业务代码挤在同一个进程里扩容、隔离、升级都很麻烦。Hangfire.HttpJob 的做法是把它们拆成两层调度中心部署 Hangfire Hangfire.HttpJob负责维护周期性任务、下发 run/stop 指令、收集执行结果与心跳。Agent 业务执行器一个独立的 ASP.NET Core 进程里面是真正的业务 Job 类通过中间件暴露/jobagent路由等待调度中心调用。上图中展示的就是调度中心的作业管理界面。在 Agent 模式下所有任务看起来是普通的周期性作业但点击进去会发现它们的Url指向的是 Agent 进程的地址业务逻辑并不在调度中心里。Agent 的注册工作由一个核心文件完成JobAgentServiceConfigurer.cs。它会在应用启动时扫描程序集把所有继承自JobAgent的类自动登记进JobAgentDic字典并按特性SingletonJobAttribute单例 /TransientJobAttribute多例 /HangJobUntilStopAttribute常驻注册到依赖注入容器。这一步是后面所有自动的基础。2. 自动注册的核心Agent 启动即向调度中心报到 自动注册的开关默认是关闭的一旦你在配置里打开EnableAutoRegister并指定调度中心地址Agent 进程一启动就会触发注册流程。这段逻辑全部封装在 JobAgentRegisterService.cs 中它是一个IHostedService随应用生命周期自动启停。它的工作流程可以概括为四步校验配置检查RegisterHangfireUrl调度中心地址和RegisterAgentHostAgent 自身对外地址是否合法不合法直接告警跳过。遍历本地 Job 字典拿出所有已注册的 JobAgent 类型跳过那些显式声明不参与自动注册的任务。调用调度中心 API通过HangfireJobClient.AddRecurringJob在调度中心创建一个周期性任务任务的Url指向 Agent 的/jobagent路由任务的AgentClass填的是命名空间.类名,程序集名调度中心凭这个字符串就能反查出对应的 Job 类。失败重试注册失败不会放弃会以 1 秒间隔自动重试最多 3 次直到成功或放弃并记录日志。值得注意的细节是RecurringJobIdentifier作为任务的唯一 ID调度中心在添加时会自动做查重重复注册会被识别为registerd状态而跳过不会产生脏数据。注册成功后你会在调度中心的周期性作业列表里看到自动出现的任务如下图的配置弹窗所示所有配置项都定义在 JobAgentOptions.cs 中包括路由地址SitemapUrl默认/jobagent、Basic 认证开关以及上面提到的两个注册地址。3. 心跳握手调度中心如何确认执行器还活着 自动注册只是一次性报到真正让调度中心与 Agent 保持联络的是心跳机制。这套机制由两端配合完成3.1 调度中心主动探测调度中心有一个常驻服务 JobAgentHeartBeatServer.cs每隔 5 秒执行一次巡检扫描所有周期性任务筛选出带AgentClass的 AgentJob按 Agent 的 Host 聚合分组向每个 Agent 发送一个带特殊 Header 的 HTTP 请求其中x-job-agent-action: heartbeat表明这是心跳探测x-job-storage告诉 Agent 调度中心用的是哪种存储Redis、Mysql、SqlServer 或 PostgreSqlAgent 的响应头里会带回自己的agentServerId调度中心把它写入activeAgent:{host}的 Hash 里作为 Agent 存活的证据。3.2 Agent 端应答并上报资源Agent 收到心跳后由 JobAgentMiddleware.cs 分发处理最终调用 Heartbeat.cs 中的HeartBeatReport完成应答每次收到调度中心的请求就把剩余心跳次数重置为 300 秒5 分钟 × 60 次每 1 秒上报一次Agent 每秒把当前进程的 CPU 使用率、内存占用WorkingSet、磁盘剩余空间、进程名等打包成ProcessInfo写入共享存储的AgentHeart:{serverId}Hash 中调度中心巡检时读取这个 Hash就能在 Dashboard 上看到每个 Agent 的存活状态、运行时间和资源占用。简单说调度中心负责喊话Agent 负责应答而两者通过共享存储交换状态。由于心跳数据写的是同一个存储即使 Agent 与调度中心不在同一台机器上也能隔空握手。上图是任务执行后的详情页可以看到JobId、请求参数、执行耗时Latency / Duration、服务器信息等完整数据。这些结果数据也是 Agent 通过共享存储回传给调度中心的_agent_result_键与心跳机制同源同理。4. 失联兜底Agent 挂掉了怎么办 再好的心跳也挡不住进程崩溃。为此项目提供了失联检查服务 LosedJobCheckServer.cs每 5 秒扫描一次处于 Processing执行中状态的任务处理两种故障调度中心自身挂了任务卡在 Processing 超过 5 分钟且调度中心 server 心跳超过 10 分钟未更新说明调度进程已死任务会被转移到 Failed 状态并发送失败通知。Agent 挂了或重启对比任务执行时记录的agentServerId与activeAgent里最新的 Agent ID如果 Agent 已经失联超过 10 分钟同样把任务标记为失败HangfireAgentShutDownError避免任务永久滞留在 Processing 里。这套兜底机制保证了无论哪一端崩溃任务都不会悬空调度系统始终处于可观测、可恢复的状态。5. 快速上手三步开启自动注册 ⚡想在项目里用上这套自动握手机制只需三步第一步调度中心引入 HttpJob 服务端在调度中心的Startup.cs中注册UseHangfireHttpJob并确保配置了与 Agent 一致的存储类型Memory、Redis、SqlServer、Mysql、PostgreSql 任选其一。第二步Agent 项目引入 Agent 包并注册在 Agent 项目的Startup.cs中调用AddHangfireHttpJobAgent默认会自动扫描入口程序集中的所有JobAgent子类services.AddHangfireHttpJobAgent();然后在appsettings.json里配置 JobAgentOptions.cs 对应字段{ JobAgent: { EnableAutoRegister: true, RegisterHangfireUrl: http://调度中心地址, RegisterAgentHost: http://本Agent对外地址, RegisterHangfireBasicName: admin, RegisterHangfireBasicPwd: 123456 } }第三步启动并观察启动 Agent 进程后打开调度中心的 Dashboard在周期性作业列表里就能看到自动注册出来的任务点击Agent管理页可以看到每个执行器的存活状态与心跳时间。整个过程零手工配置这就是自动握手的完整闭环。6. 总结Hangfire.HttpJob 的Agent自动注册机制用注册 心跳 失联兜底三层设计优雅地解决了任务调度与业务分离场景下的服务发现难题自动注册Agent 启动即通过 API 向调度中心登记任务失败自动重试心跳握手调度中心 5 秒一次探测Agent 每秒回传资源数据双方通过共享存储保持状态同步失联兜底任意一端崩溃滞留任务都会被自动标记失败不会无限悬挂。如果你正在为调度和业务拆开部署后如何互相发现而头疼这套机制值得直接借鉴。核心实现都在 Server/Hangfire.HttpJob/Server/JobAgent 与 Agent/Hangfire.HttpJob.Agent 目录下对照源码阅读理解会更加透彻。【免费下载链接】Hangfire.HttpJobhttpjob for Hangfire,restful api for Hangfire,job调度与业务分离项目地址: https://gitcode.com/gh_mirrors/ha/Hangfire.HttpJob创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考