Hangfire 分布式后端作业调度框架服务

本文详细介绍Hangfire开源作业调度框架的安装、配置与使用流程。通过实例展示如何在MVC项目中集成Hangfire,实现任务调度、延时执行及周期性任务等功能。并介绍如何使用SQL Server作为存储后端,以及仪表盘的权限设置。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

这是一款开源的作业调度框架

github地址 https://github.com/HangfireIO/Hangfire

官网 https://www.hangfire.io/

中文文档 https://www.bookstack.cn/read/hangfire-zh/blankquick-start

这边分享一下我从建立项目到部署的一个简单的例子:

首先新建一个空的framework版本的MVC项目

然后执行

PM> Install-Package Hangfire
PM> Install-Package Hangfire.AspNet

这样程序会将hangfire依赖的包下载安装到项目中,然后给项目添加OwinStartup类

然后在Startup类中对hangfire进行初始化

1、使用仪表盘

2、使用sqlserver数据库

3、因为仪表盘只能在本地访问,服务器访问返回401,所以需要权限过滤添加一个账户,在访问仪表盘页面的时候输入账号密码即可进行访问,密码可以直接使用字符串如下,如果想保存为字节类型的则需要将明文的密码转换成字节形式代码如下

using Hangfire;
using Hangfire.Dashboard;
using Hangfire.SqlServer;
using Microsoft.Owin;
using Owin;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;

[assembly: OwinStartup(typeof(HangFireTest.Startup))]
namespace HangFireTest
{
    public class Startup
    {
        private IEnumerable<IDisposable> GetHangfireServers()
        {
            GlobalConfiguration.Configuration
                .SetDataCompatibilityLevel(CompatibilityLevel.Version_170)
                .UseSimpleAssemblyNameTypeSerializer()
                .UseRecommendedSerializerSettings()
                .UseSqlServerStorage("Data Source=10.18.193.200; Initial Catalog=HangfireTest; User ID=sa;Password=123456", new SqlServerStorageOptions
                {
                    CommandBatchMaxTimeout = TimeSpan.FromMinutes(5),
                    SlidingInvisibilityTimeout = TimeSpan.FromMinutes(5),
                    QueuePollInterval = TimeSpan.Zero,
                    UseRecommendedIsolationLevel = true,
                    UsePageLocksOnDequeue = true,
                    DisableGlobalLocks = true
                });

            yield return new BackgroundJobServer();
        }

        public void Configuration(IAppBuilder app)
        {
            app.UseHangfireAspNet(GetHangfireServers);
            var filter = new BasicAuthAuthorizationFilter(
              new BasicAuthAuthorizationFilterOptions
              {
                  SslRedirect = false,
                  // Require secure connection for dashboard
                  RequireSsl = false,
                  // Case sensitive login checking
                  LoginCaseSensitive = false,
                  // Users
                  Users = new[]
                  {
                        //new BasicAuthAuthorizationUser
                        //{
                        //    Login = "Administrator-1",
                        //    // Password as plain text
                        //    PasswordClear = "test"
                        //},
                        new BasicAuthAuthorizationUser
                        {
                            Login = "admin",//用户名
                            // Password as SHA1 hash
                           // Password = new byte[]{  0x9f,0x71,0x30,0xf4,0x22,0x90,0xd0,0xe0,0xce,0x5a,0x8a,0x7a,0x09,0xd2,0xba,0x75,0x53,0x6d,0x05,0x64 }//密码
                           PasswordClear="123456"
                        }
                  }
              });
            var options = new DashboardOptions
            {
                AuthorizationFilters = new[] {
                    filter
                }
            };
            app.UseHangfireDashboard("/Hangfire", options); //可以改变Dashboard的url
            // Let's also create a sample background job
            //立即执行
            BackgroundJob.Enqueue(() => Debug.WriteLine("Hello world from Hangfire!"));
            //BackgroundJob.Enqueue<EIPNewsSync>(x => x.AsyncNews());
            //立即执行调用后台方法
            BackgroundJob.Enqueue(() => new MyTasks().DoAsync());
            //可以设置延迟执行
            BackgroundJob.Schedule(
             () => Console.WriteLine("延迟了2分钟执行!"),
                 TimeSpan.FromMinutes(2));
            //可以设置定时执行循环执行
            RecurringJob.AddOrUpdate<EIPNewsSync>(x => x.AsyncNews(), "0 */5 * * * ?");//Cron语法 每5分钟执行一次

        }
    }
}
            string password = "qwe123!";//将密码转换为字节形式
            using (var cryptoProvider = System.Security.Cryptography.SHA1.Create())
            {
                byte[] passwordHash = cryptoProvider.ComputeHash(Encoding.UTF8.GetBytes(password));
                string result = "new byte[] { " +
                    String.Join(",", passwordHash.Select(x => "0x" + x.ToString("x2")).ToArray())

                    + " } ";
            }

这边可以对任务进行很多的操作,细节见官方文档,这边只做一个记录,定时可以使用系统内置的Cron.中的方法,每天每分钟每月等等,需要特殊的定时可以查询Cron语法写入即可

比如我们这边发布后访问http://10.18.193.200:2800/Hangfire

这里将代码中的账号密码输入即可访问到仪表盘

我们可以清楚的查看执行过的作业内容,并可以重新加入队列中进行执行

在周期性作业菜单中可以看到我们设置的每5分钟执行一次的内容,包括立即执行、删除、最后执行时间、下次执行时间等等

在服务器中,可以看到运行的服务器信息,心跳等

### Hangfire 的实现原理与源码分析 Hangfire 是一种用于 .NET 和 .NET Core 平台的分布式任务调度框架,其设计目标是提供简单易用、可靠的后台任务管理功能。以下是关于 Hangfire 实现原理及其分布式任务调度的核心要点: #### 1. **持久化存储** Hangfire 使用外部数据库作为持久化层,支持多种存储后端(如 SQL Server、Redis、PostgreSQL 等)。这些数据库不仅保存了任务的状态信息,还记录了任务的历史执行情况和日志。 - 当创建一个新的任务时,Hangfire 将该任务序列化并将其写入到指定的存储中[^1]。 - 如果应用程序崩溃或重启,Hangfire 可以从存储中恢复未完成的任务,并重新尝试执行它们。 #### 2. **队列机制** Hangfire 内部实现了基于优先级的消息队列系统。当一个任务被加入队列时,它会被标记为“等待”状态。一旦有可用的工作线程,任务就会从队列中取出并进入“处理中”状态。 ```csharp public class BackgroundJobServerOptions { public int WorkerCount { get; set; } = Environment.ProcessorCount; } ``` 上述代码片段展示了如何设置工作线程的数量,默认情况下会根据 CPU 核心数动态调整[^1]。 #### 3. **分布式锁** 为了防止同一任务在多个节点上重复执行,Hangfire 利用了分布式锁技术。具体来说,每当某个服务器实例试图获取一项任务时,都会先尝试加锁。如果成功,则允许执行;否则跳过当前任务转而寻找其他可执行项。 这种机制确保了即使存在多个运行中的 Hangfire 节点,也不会发生冲突或者资源竞争的情况[^1]。 #### 4. **自动重试机制** 对于可能出现暂时性错误的操作(例如网络超时),Hangfire 提供了一套内置的重试策略。开发者可以通过配置自定义最大重试次数以及每次间隔的时间长度。 ```csharp BackgroundJob.Enqueue(() => Console.WriteLine("Hello, world!"), new EnqueueOptions { Attempts = 5 }); ``` 在此例子中设置了最多五次失败后的再次尝试机会[^1]。 #### 5. **API 设计与灵活性** Hangfire 提供了一系列简洁明了的方法来满足不同类型的业务需求,包括但不限于立即执行型任务(`Enqueue`)、延时触发型任务(`Schedule`)以及循环定时器(`RecurringJob.AddOrUpdate`)[^1]。 --- ### 源码层面的关键组件剖析 #### a) 存储适配器 (Storage Adapter) 每种受支持的数据存储都有对应的适配类负责实际交互操作。例如针对 Redis 的 `RedisStorage` 或者面向关系型数据库的 `SqlStorage`. #### b) 工作池管理 (Worker Pool Management) 通过继承抽象基类 `IBackgroundProcess`, 各个工作进程能够监听来自特定主题的新事件通知,并及时响应处理请求。 #### c) 序列化/反序列化过程 由于需要跨进程甚至跨机器传递参数对象,因此必须依赖高效的二进制编码方案。默认采用 JSON 形式表示复杂结构体的内容[^3]. --- ### 总结 综上所述,Hangfire 凭借强大的架构设计理念,在保障高并发环境下的稳定性方面表现优异。无论是简单的短生命周期作业还是复杂的长期计划安排都能轻松应对。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值