HangFire快速入门 分布式后端作业调度框架服务
安装
NuGet 上有几个可用的Hangfire 的软件包。如果在ASP.NET应用程序中安装HangFire,并使用Sql Server作为存储器,那么请在Package Manager Console窗口中键入以下命令:
PM> Install-Package Hangfire
配置
在安装package后,添加或者更新以下几行到Owin Startp类:

using Hangfire; // ... public void Configuration(IAppBuilder app)
{
GlobalConfiguration.Configuration.UseSqlServerStorage("<connection string or its name>"); app.UseHangfireDashboard();
app.UseHangfireServer();
}

需要配置授权
默认情况下,只有本地有权限访问Hangfire仪表板。如果需要授权远程访问,那么仪表板的授权必须进行相应的配置。
然后打开Hangfire仪表板来测试您的配置。编译项目并在浏览器中打开以下URL:
|
1
|
http://<your-site>/hangfire |
用法
添加工作
HangFire处理不同类型的后台任务,并且使用一个独立的上下文环境调用他们。
Fire-And-forget(发布/订阅)
这是一个主要的后台任务类型,持久化消息队列会去处理这个任务。当你创建了一个发布/订阅任务,该任务会被保存到默认队列里面(默认队列是"Default",但是支持使用多队列)。多个专注的工作者(Worker)会监听这个队列,并且从中获取任务并且完成任务。
BackgroundJob.Enqueue(() => Console.WriteLine("Fire-and-forget"));
延迟
如果想要延迟某些任务的执行,可以是用以下任务。在给定延迟时间后,任务会被排入队列,并且和发布/订阅任务一样执行。
BackgroundJob.Schedule(() => Console.WriteLine("Delayed"), TimeSpan.FromDays(1));
循环
按照周期性(小时,天等)来调用方法,请使用RecurringJob类。在复杂的场景,您可以使用CRON表达式指定计划时间来处理任务。
RecurringJob.AddOrUpdate(() => Console.WriteLine("Daily Job"), Cron.Daily);
连续
连续性允许您通过将多个后台任务链接在一起来定义复杂的工作流。
var id = BackgroundJob.Enqueue(() => Console.WriteLine("Hello, "));
BackgroundJob.ContinueWith(id, () => Console.WriteLine("world!"));
释放
Hangfire将您的任务保存到持久化库汇总,并且以可靠的方式处理它们。这意味着,你可以中断Hangfire Worder的线程,重新加载应用程序域,或者终止程序,即使这样您的任务仍会被处理。只有在你代码的最后一行执行完成,Hangfire才会标记这个任务完成。并且知道任务可能在最后一行代码执行之前失败。它包含多种 自动-重试机制,它可以自动处理在存储或代码执行过程中发生的错误。
这对于通用托管环境(如IIS Server)非常重要。它们可以包含不同的优化,超时和错误处理代码(可能导致进程终止)来防止不好的事情发生。如果您没有使用可靠的处理和自动机制,您的工作可能会丢失。您的最终用户可能无限期等待某些任务,如电子邮件,报告,通知等。
但是当您的存储空间破损时,Hangfire无法做任何事情。请为您的存储使用不同的故障切换策略,以保证在发生灾难时处理每个作业。
原文地址:http://docs.hangfire.io/en/latest/quick-start.html
HangFire简述:
分布式后端作业调度框架服务,我们只需要关心业务逻辑代码,而不用关心调度机制,支持.net framework和.net core
HangFire基本结构:
客户端(创建任务)、服务端(执行任务)、数据库(存储任务列表和执行状况)、仪表盘(在网站上对任务进行监控查看和各种操作)
HangFire适用场景:
定时执行任务、循环执行任务、异步执行耗时任务、A任务执行完成再执行B任务、批量执行任务
HangFire官网: https://www.hangfire.io/
HangFire中文文档:http://koukouge-hangfire.daoapp.io/quick-start.html
HangFire英文文档:http://docs.hangfire.io/en/latest/quick-start.html
HangFire源码地址: https://github.com/HangfireIO
实战经验分享:
网上资料不是很多 都是按照官方例子在讲解,缺少很多关键性的概念讲解,导致很多伙计在实战中遇到各种坑。
1、客户端:创建任务-->1、配置HangFire数据库连接 2、创建任务(在创建任务的时候HangFire会自动将任务序列化并存储到数据)
2、服务端:执行任务-->1、配置HangFire数据库连接 2、从HangFire数据库系统表读取客户端创建的任务然后开线程并行执行,任务之间不冲突。(服务端可宿主在Windows服务、控制台程序、IIS中…)
3、数据库:HangFire程序框架表-->创建任务的时候HangFire会自动生成无需关心,但要注意如果采用现有的数据库,必须保证数据库中没有重名的表,否则你懂(aggregatedcounter、counter、distributedlock、hash、job、jobparameter、jobqueue、jobstate、list、server、set、state),数据库可采用 MySQL ,MSSQL,Redis视需要而定
4、仪表盘:展示作业列表执行状态和结果等相关信息-->在.Net WebForm或.Net MVC 或.NetCore MVC网站程序对接HangFire数据库,MVC 对接方式和WebForm略微不同 请参考官方文档
如何正确理解架设部署上述4个板块:
重点说客户端、服务端、仪表盘直之间的关系,数据库就不用多说了
方案1(不推荐):客户端A、服务端B、仪表盘C 分别运行在3个独立的项目中
优缺点:没什么优点,而且AB分开会导致服务端B从数据库提取任务列表,准备反向加载程序集执行任务的时候,在自己的程序代码中找不到对应的业务逻辑代码或者引用类,因为业务逻辑代码是在客户端A项目中创建,自然业务逻辑类及功能代码都在A项目的程序集中,自然找不到。
例子:客户端A创建的作业是引用YourOwnJobLibrary.dll类中 ShowMeTheMoney() 方法,而服务端B中没有引用YourOwnJobLibrary.dll 所以无法执行任务ShowMeTheMoney(),
报错:System.IO.FileNotFoundException
Could not load file or assembly 'DotNetFrameWorkConsoleApplicationHangFire, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. ???????????
System.IO.FileNotFoundException: Could not load file or assembly 'DotNetFrameWorkConsoleApplicationHangFire, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'. ???????????
File name: 'DotNetFrameWorkConsoleApplicationHangFire, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'
at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMarkHandle stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName, ObjectHandleOnStack type, ObjectHandleOnStack keepalive)
at System.RuntimeTypeHandle.GetTypeByName(String name, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark, IntPtr pPrivHostBinder, Boolean loadTypeFromPartialName)
at System.RuntimeType.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase, Boolean reflectionOnly, StackCrawlMark& stackMark)
at System.Type.GetType(String typeName, Boolean throwOnError, Boolean ignoreCase)
at Hangfire.Storage.InvocationData.Deserialize()
解决方案:让服务端B也引用YourOwnJobLibrary.dll即可,但是这并不是我们想要的结果,以后更新服务什么的还得两头更新很麻烦。
方案2(推荐):客户端A、服务端B在同一个项目中,仪表盘C独立网站项目中
优缺点:这样比较合理,更新服务方便,即便没有仪表盘C,作业正常调度执行;适合后台相对固定的作业。
可以将AB放在Windows服务项目中(VS中可以创建),这样系统重启什么的毫无顾虑,更新服务程序的时候只需停止服务->替换程序->开启服务即可。
方案3(还行):客户端A、服务端B、仪表盘C在同一网站项目只能是网站项目,因为仪表盘只能在Web项目(API、WebForm、MVC )中
优缺点:视情况也未尝不可,如果宿主在IIS中,IIS默认20分钟没有人访问会停止,HangFire作业服务也会定制,可将此时间在IIS配置中延长,比较适合任务经常需要灵活变动处理的场景。
重要信息备注:
注1:创建任务可以是在控制台程序Main方法中执行一次把任务Load到数据库,或则在网站上用户点击某个按钮执行后端方法创建。
注2:服务端比较灵活,可宿主在Windows服务、控制台程序、IIS中…
注3:首次启动连接数据库时,会自动生成12张系统表,请确保现有库中不存在以下表名:aggregatedcounter、counter、distributedlock、hash、job、jobparameter、jobqueue、jobstate、list、server、set、state
注4:原则上同一台电脑上只需要1个服务端存在,测试中发现这么一种情况:服务端B宿主在D控制台程序中,因误操作在仪表盘C网站项目中也启动一个HangeFire宿主服务E,最后的结果是服务端B的程序失效,服务端E正常运作,但是仪表盘上显示找不到任务作业对应的程序集,因为程序集在服务端B程序中,如方案1的System.IO.FileNotFoundException…
注5:HangFire执行的任务里面如果涉及到C盘创建文件夹 可能会因为权限问题 创建失败,采用管理员权限运行程序即可创建
实例:按照方案2思路测试
- 创建一个.net core 2.0控制台项目(.net framework/.net core2.0都行)
- 安装nuget Hangfire(针对控制台程序可以只安装Hangfire.core即可 )
- 安装nuget HangFire.MySql.Core(.net framework 也引用此包 如果用HangFire.MySql 下面的配置数据库链接事变)
- 安装好后就可以在Main方法中使用了

注:控制台程序关闭,也就是HangFire宿主程序停止,作业无法继续执行,想检测服务作业是否在执行,可定时往记事本中写入当前时间。
5、网站(.net core)中配置HangFire仪表盘:( .net framework 的网站配置不一样 尚未测试)
注1:app.UseHangfireDashboard(); 是让网站仅仅可以访问HangFire数据库的作业详情,不负责业务代码的执行。
注2:app.UseHangfireServer();是让HangFire服务宿主在Web程序中,参加上面方案2和方案3,如果是方案2则不应该添加此语句,方案3则添加此语句。
运行项目访问HangFire仪表盘: http://localhost:56013/hangfire/

HangFire快速入门 分布式后端作业调度框架服务的更多相关文章
- HealthKit开发快速入门教程之HealthKit框架体系创建健康AppID
HealthKit开发快速入门教程之HealthKit框架体系创建健康AppID HealthKit开发准备工作 在开发一款HealthKit应用程序时,首先需要讲解HealthKit中有哪些类,在i ...
- 快速入门分布式消息队列之 RabbitMQ(2)
目录 目录 前文列表 RabbitMQ 的特性 Message Acknowledgment 消息应答 Prefetch Count 预取数 RPC 远程过程调用 vhost 虚拟主机 插件系统 最后 ...
- 快速入门分布式消息队列之 RabbitMQ(3)
目录 目录 前文列表 前言 通道 Channel 一个基本的生产者消费者实现 消费者 生产者 运行结果 应用预取计数 应用 ACK 机制 最后 前文列表 快速入门分布式消息队列之 RabbitMQ(1 ...
- 快速入门分布式消息队列之 RabbitMQ(1)
目录 目录 前言 简介 安装 RabbitMQ 基本对象概念 Message 消息 Producer 生产者 Consumer 消费者 Queue 队列 Exchange 交换机 Binding 绑定 ...
- .NET之Hangfire快速入门和使用
前言: 定时任务调度问题,是一个老生常谈的问题.网上有许多定时任务调度的解决方案,对于我而言很早以前主要是使用Window计划和Window服务来做任务定时执行,然后就开始使用定时任务调度框架Quar ...
- webservice快速入门-使用wsimport生成ws服务端(二)
上个例子演示的是在当前项目下发布的Webservice Server,而实际应用中和Client是分离的,本文介绍两种客户端开发方式: 1.导出WebService服务端服务接口到jar包,客户端引入 ...
- thinkphp快速入门(学习php框架及代码审计)
之前想学习php代码审计,但是没有坚持下去,记得当时看到了很多CMS框架采用MVC架构,就嘎然而止了. 为了深入学习下框架,一边看着thinkphp官方文档,一边写个简单的登陆注册页面以加深理解. 官 ...
- ❤️❤️爆肝3万字整理小白快速入门分布式版本管理软件:Git,图文并茂(建议收藏)--已码一万字❤️❤️
@ 目录 什么是Git SVN VS Git 什么是版本控制 安装Git 谁在操作? Git本地仓库 本地仓库构造 重点 Git基本操作 git add git commit git diff git ...
- Hibernate入门第一讲——Hibernate框架的快速入门
Hibernate框架的概述 什么是框架? 框架指的是软件的半成品,已经完成了部分功能. JavaEE开发的三层架构 了解框架的基本概念之后,我们就来看看Hibernate框架处于JavaEE开发的经 ...
随机推荐
- LA4080/UVa1416 Warfare And Logistics 最短路树
题目大意: 求图中两两点对最短距离之和 允许你删除一条边,让你最大化删除这个边之后的图中两两点对最短距离之和. 暴力:每次枚举删除哪条边,以每个点为源点做一次最短路,复杂度\(O(NM^2logN)\ ...
- 2017-12-20python全栈9期第五天第一节之昨日内容回顾和作业讲解之字母变大写
#!/user/bin/python# -*- coding:utf-8 -*-lis = [2,3,'k',['qwe',20,['k1',['tt','3','1']],89],'ab','adv ...
- Android studio Error: Modules no specified解决和真机调试
如何配置SDK百度一大堆: 前言:Android Studio很完善,如果SDK配置好,理论上就是 创建项目->创建个APP(名字自己随便起)->打开手机开发者模式运行即可:如果出了问题, ...
- 使Python走向Effective系列目录
Effective以一词,并不单单局限于执行速度层面的高效率,同时有着令代码易于阅读.易于测试且易于维护等意思,此外,它还蕴藏着易于扩展.易于修改和易于多人协作等更为高阶的理念.如果能够通过一些具体的 ...
- HBase 在HDFS上的物理目录结构
根目录 配置项 hbase.rootdir 默认 "/hbase" 根级文件 /hbase/WALs 被HLog实例管理的WAL文件. /hbase/WALs/data-hbase ...
- P3396 哈希冲突
很好的根号算法(这种思想好像叫根号分治?) 首先,暴力是Ο(n2)的 考虑预处理: for(p=1;p<=n;p++) //枚举模数 ans[p][i%p]+=value[i]; 看似很好但还是 ...
- JavaScript表单验证的相关事件
1. 表单元素: a) Input标签:文本框(text)—密码框(password)—单选—复选框—文件—图像—隐藏—按钮—提交—重置,表单元素都在input标签 b) ...
- python2x如何迁移代码到python3中
2to3 - 自动Python 2到3代码转换 2to3是一个Python程序,它读取Python 2.x源代码并应用一系列修复程序将其转换为有效的Python 3.x代码.标准库包含一组丰富的修复程 ...
- TCP、UDP通信
开放系统互连参考模型 (Open System Interconnect 简称OSI) OSI七层模型 1.应用层2.表示层3.会话层4.传输层5.网络层6.数据链路层7.物理层 TCP/IP模型1. ...
- cnpm下载包与npm版本不一致的问题解决
参考链接:https://www.jianshu.com/p/949b4e0ae190
