【框架学习与探究之定时器--Hangfire】

声明

本文欢迎转载,请注明文章原始出处:http://www.cnblogs.com/DjlNet/p/7603632.html


前言

上篇文章当中我们知道关于Quartz.NET的一些情况,其实博主再写Quartz.Net的时候也注意到了我们今天需要了解的Hangfirehttps://www.hangfire.io之所以为何我们在了解Quartz.Net的同时还去了解另一款定时任务框架呐?这里博主抱着好奇的心态,听说此框架各种各种好,但是博主本来觉得Quartz.Net历经岁月之后本身已经挺优秀的了且已经支持.net core了beta版,噢耶!!,所以我们还是对Hangfire来个一探究竟吧,顺便也能对比一下它们之间异同....

废话时间:今天(2017年10月21日12:00:46)是S7全球总决赛系列赛事的LPL队伍上场的日子,虽然博主偶尔和老铁们玩玩LOL,但是对于电竞带来的那种热情和团队精神所深受感动鼓舞,而当今再也没有洪水猛兽的杨叫兽了,这话总超级扭曲的东西存在了,电竞也成了一项新的行业支撑数以千计的人在为之奋斗!好了,不扯远了,就当博主从竞技比赛中,看到的是为之奋斗人们的汗水和努力吧!!!游戏并不一定是毒药,它也可以是催化剂,就得施药人的手法了!


Hangfire文档划重点

这里博主首先把英文官方文档通刷了一边,基本整体感觉是差不多能有的都有了,当然也是支持.net core的,更加着重于框架本身的易用性和用户体验相关的东西,导致我都觉得不像是在看一个框架或者东西,而是处于一种再看一个产品的眼光了,是的,它还是确实是一款收费的产品了Hangfire Pro这个收费了,不过基本感觉收费的功能也就那样,一般情况感觉开发者还是够了哈......接着博主在园中一搜不出所料,原来很多老铁都已经用上了此框架,也说明了一定的影响力了,还有些.NET开发者在推动这玩意儿的发展,那么我们还是老规矩带着文档的着重点以及园中园友的研究一起看看这玩意儿的优缺点!!!


Hangfire设计上面的思考

这里首先引用官方的示意图,然后我们接着分析这样设计以及相比于Quartz.Net的设计而言它们的异同之处(Quartz.Net设计图参考博主上文地址)

从图中可以看出,整体组织结构的设计上面分成主要的三大块:
1、任务存储器JobStorage
2、客户端添加对应类型的任务BackgroundJobClientBackgroundJobRecurringJob
3、任务处理器处理存储中待处理的任务BackgroundJobServer
由这三者共同协作完成任务的添加到存储到执行的一整条使用链。

这里我们回想一下Quartz.Net的组织结构(主要成分是1、任务JobDetail;2、触发器Trigger;3、任务与触发器存储Storage;4、调度器Scheduler),也可能是因为定时器本身使用需求所致,到这里不知道大家有木有感受到两者的大体设计考虑上很多相似之处
a、同样的组件式职责分离设计;
b、同样都支持持久化存储利用数据库锁支持多实例集群;
c、框架本身都支持较好的扩展winservice、topshelf、ioc等等和使用包含多种任务类型与Cron表达式等等

从这里也给我们开发者一个思考就是在设计一个框架是所需要考虑的问题,所以从上面来看出于设计而言,大家基本都是该做到的都做到,也基本二者选其一都可以满足一般业务需求了,只是在具体实现上面大家侧重点可能颇有不同罢了,接下来关于不同之处不限于设计也包括使用层面:

a、Hangfire的设计到实现的思路是通过序列化 [Newtonsoft.Json] 任务持久化到数据库(泛指且不是RAM模式且RAM模式需要第三方包才支持),这样一来就完全隔离了Job与JobProcessor之间的关系,因为它们之间的纽带是Queue已经在落地数据库层面了,从这里也可以看出作者是更加注重于功能独立且更加偏向引导使用者更加关注于自己的业务逻辑方便集成进来方便,也看得出来作者的心意了哈,所以相对而言通过队列使得二者貌似不知道对方的存在一样,这样设计巧妙的规避了任务创建和任务调度之间复杂和交织的关系,同样带来的负面效应就是基于数据库来支持增加了依赖项以及受限于数据库连接数的性能瓶颈的影响(不过一般都不是事儿),但是这里需要注意的一点就是虽然不用相互感知,但是需要client在添加任务的时候以及server在调度执行任务是它们使用的相关class、assembly需要所共有,不然解析不了的。相比之下 Quartz.Net 就需要在代码级别层面 Scheduler 与 Trigger 或者 JobDetail 耦合,同样可以持久化到数据库做到多机部署,延续了一直以来的设计思路且相互之间可以组合可实现可配置复杂的应用开发,且不说那种方式好,这是指出它们的思路不同之处,好不好不是我说算,是技术选型和使用者的感受来定的,切莫为了捧一个而故意摔另一个就不好了,站在思考欣赏的角度看问题就好....

b、Quartz.Net支持秒级单位的定时任务处理,但是Hangfire只能支持分钟及以上的定时任务处理,原因在于Hangfire用的是开源的NCrontab组件,跟linux上的crontab指令相似,且Quartz.Net支持任务和触发器之间的组合使用构建复杂的关系,Hangfire在指定任务时就需要指定类型和调度规则,是一一对应关系,这个得看使用者需求对于这两者的需求度如何而定,并没有必选项

c、UI控制台方面:这里Hangfire对于任务UI(Hangfire Dashborad)方面展示下了功夫了,界面简洁展示信息充足而且支持自定义扩展,不限于Job、Queue、Server、Detail等信息以及统计结果,这里基本上都满足了开发者的监控需求了,且还图表可以查看每天/周的大致情况,支持手动重启任务删除查看详情等等,相比Quartz.Net官方是没提供UI控制台界面,由社区开发者提供了一个第三方扩展的UI界面,也大致能够做到展示统计信息和运行情况,还算是朴实简洁,这里博主还是更加偏向于Hangfire的界面更加分一些,哈哈!Hangfire这里还包含UI界面的访问权限控制,貌似Quartz.Net的扩展https://github.com/guryanovev/CrystalQuartz木有权限控制,所以被坏人知道地址就麻烦了,当然也可以自己找方法ip过滤白名单之类的,或者加上基本权限过滤改写默认实现......

所以综上的话,一般情况如果对整体任务的统计以及详情查看UI界面和易用性上面考虑的话,Hangfire 也可以出作为技术选型的一个参考选择,以及对于时间刻度上面的要求可以接受分钟级别的话就可以考虑使用这种来的直接的框架,Quarzt.Net 对于没怎么使用过的老铁来说,结构组织略微比 Hangfire 代码上面编写复杂些了吧...


Hangfire 文档选择性记录

BackgroundJobClientBackgroundJobRecurringJob客户端主要的3个类的API分别表示了可以添加不同类型的Job到storage当中,会序列化方法信息(所以这里API是通过表达式来传递,可以是静态方法或者实例方法,这样就可以通过表达式才能来命名任务job名字)及其所有参数,根据序列化信息创建一个新的后台作业,将后台作业保存到持久存储,将后台作业排入队列,所以并不会立即调用方法。然后接着由服务端启动的工作线程处理,获取下一个工作并与其他工作线程互斥的拿取任务,执行作业及其所有扩展过滤器,最后执行完毕从队列中删除该作业。

1、使作业任务如果需要传递参数尽量小而简单,方法调用(即作业)在后台作业创建过程中被序列化,使用TypeConverter类将参数转换为JSON字符串。如果您有复杂的实体和/或大对象;包括数组,最好将它们放入数据库,然后将其身份(例如传递userid、orderid 之类的)只传递给后台作业。

2、使用 DisableConcurrentExecution(timeout) ,[AttributeUsage(AttributeTargets.Class | AttributeTargets.Interface | AttributeTargets.Method)],可以把此标记方法或者类或者接口上面,可以使得执行的任务防止并发

写到这里发现文档当中的东西,好像还真没什么可以写了( 尴尬,捂脸! ),可能也是单纯看文档的缘故吧,没有把应用于实际项目当中的话,对于一些套路的使用以及设计可能也只能存在一些想法但是并没有实战,所以在于后面文章当中,可能就不会就单单对于框架本身的使用啥的过多的了解,需要尽可能把框架集成到系统当中去使用起来,之后再把途中遇到的问题记录下来....


照例备份园中同类型文

1、Hangfire项目实践分享 http://www.cnblogs.com/ecin/p/hangfire-best-practice.html
2、开源的.NET定时任务组件Hangfire解析 http://www.cnblogs.com/pengze0902/p/6583119.html
3、.NET Core开源组件:后台任务利器之Hangfire http://www.cnblogs.com/chenug/p/6655636.html#top
4、执行后台任务的利器——Hangfire http://www.cnblogs.com/heyu/articles/6404336.html


总结

可能此文,总的来说主要是博主对于此框架关于设计上面的一些自己的思考和解读,以及与 Quartz.Net 的设计上面的对比以及一些各自的着重点偏向与使用者的需求吧,其次就是关于文档当中的一些主要对象的解读和对于任务的一系列操作流程等等,所以总之啦,无论使用那种关于定时器的框架,都要遵循一些大家共识的原则,例如:任务job参数传递的原则之类的,还有就是尽可能遵循各自框架当中所写到的一些最佳使用法制。可能博主在框架学习的路上越走越远,越走越迷,为什么呐?博主常常问自己,在了解如何使用某某框架之后,自己得到的是什么,又知道了些什么,所以框架是学不会完的,那博主就可能不会局限于框架的学习了,更加需要在理论和概念的学习与思考上面下功夫了...

此文是博主对于hangfire的一些小记录,如果对您有一点点帮助,您的评论和点赞都是对博主很大的支持!

posted @ 2017-10-26 09:36  DJLNET  阅读(2639)  评论(2编辑  收藏  举报