当前位置: 首页 > news >正文

网站常州建设上海外贸财经大学

网站常州建设,上海外贸财经大学,免费w网站建设,营销策划公司名字项目中使用Hangfire已经快一年了#xff0c;期间经历过很多次的试错及升级优化#xff0c;才达到现在的稳定效果。趁最近不是太忙#xff0c;自己在github上做了个案列#xff0c;也是拿来跟大家分享下#xff0c;案例是从项目里剥离出来的#xff0c;有兴趣的可以访问 这… 项目中使用Hangfire已经快一年了期间经历过很多次的试错及升级优化才达到现在的稳定效果。趁最近不是太忙自己在github上做了个案列也是拿来跟大家分享下案例是从项目里剥离出来的有兴趣的可以访问 这里. 什么是Hangfire Hangfire 是一个开源的.NET任务调度框架目前1.6版本已支持.NET Core。个人认为它最大特点在于内置提供集成化的控制台,方便后台查看及监控 另外Hangfire包含三大核心组件客户端、持久化存储、服务端官方的流程介绍图如下 从图中可以看出这三个核心组件是可以分离出来单独部署的例如可以部署多台Hangfire服务提高处理后台任务的吞吐量。关于任务持久化存储支持SqlserverMongoDbMysql或是Redis等等。 Hangfire基础 基于队列的任务处理(Fire-and-forget jobs) 基于队列的任务处理是Hangfire中最常用的客户端使用BackgroundJob类的静态方法Enqueue来调用传入指定的方法或是匿名函数Job Queue等参数. var jobId BackgroundJob.Enqueue(() Console.WriteLine(Fire-and-forget!)); 在任务被持久化到数据库之后Hangfire服务端立即从数据库获取相关任务并装载到相应的Job Queue下在没有异常的情况下仅处理一次若发生异常提供重试机制异常及重试信息都会被记录到数据库中通过Hangfire控制面板可以查看到这些信息。 延迟任务执行(Delayed jobs) 延迟计划任务跟队列任务相似客户端调用时需要指定在一定时间间隔后调用 var jobId BackgroundJob.Schedule(() Console.WriteLine(Delayed!),TimeSpan.FromDays(7)); 定时任务执行(Recurring jobs) 定时循环任务代表可以重复性执行多次支持CRON表达式 RecurringJob.AddOrUpdate(() Console.WriteLine(Recurring!),Cron.Daily); 延续性任务执行(Continuations) 延续性任务类似于.NET中的Task,可以在第一个任务执行完之后紧接着再次执行另外的任务 BackgroundJob.ContinueWith(jobId,() Console.WriteLine(Continuation!)); 其实还有批量任务处理批量任务延续性处理(Batch Continuations)但这个需要商业授权及收费。在我看来官方提供的开源版本已经基本够用。 与quartz.net对比 在项目没有引入Hangfire之前一直使用的是Quartz.net。个人认为Quartz.net在定时任务处理方面优势如下 支持秒级单位的定时任务处理但是Hangfire只能支持分钟及以上的定时任务处理 原因在于Hangfire用的是开源的NCrontab组件跟linux上的crontab指令相似。 更加复杂的触发器日历以及任务调度处理可配置的定时任务 但是为什么要换Hangfire? 很大的原因在于项目需要一个后台可监控的应用不用每次都要从服务器拉取日志查看在没有ELK的时候相当不方便。Hangfire控制面板不仅提供监控也可以手动的触发执行定时任务。如果在定时任务处理方面没有很高的要求比如一定要5s定时执行Hangfire值得拥有。抛开这些Hangfire优势太明显了 持久化保存任务、队列、统计信息重试机制多语言支持支持任务取消支持按指定Job Queue处理任务服务器端工作线程可控即job执行并发数控制分布式部署支持高可用良好的扩展性如支持IOC、Hangfire Dashboard授权控制、Asp.net Core、持久化存储等 说了这么多的优点我们可以有个案例例如秒杀场景用户下单-订单生成-扣减库存Hangfire对于这种分布式的应用处理也是适用的最后会给出实现。 Hangfire扩展 重点说一下上面提到的第8点Hangfire扩展性大家可以参考 这里有几个扩展是很实用的. Hangfire Dashborad日志查看 Hangfire.Console提供类似于console-like的日志体验与Hangfire dashboard集成 用法如下 public void SimpleJob(PerformContext context){context.WriteLine(${DateTime.Now.ToString(yyyy/MM/dd HH:mm:ss)} SimpleJob Running ...);    var progressBar context.WriteProgressBar();    foreach (var i in Enumerable.Range(1, 50).ToList().WithProgress(progressBar)){System.Threading.Thread.Sleep(1000);} } 不仅支持日志输入到控制面板也支持在线进度条展示. Hangfire Dashborad授权 Hangfire.Dashboard.Authorization这个扩展应该都能理解给Hangfire Dashboard提供授权机制仅授权的用户才能访问。其中提供两种授权机制 OWIN-based authenticationBasic authentication 可以参考提供案例 我实现的是基本认证授权: var options new DashboardOptions {AppPath HangfireSettings.Instance.AppWebSite,AuthorizationFilters new[]{        new BasicAuthAuthorizationFilter ( new BasicAuthAuthorizationFilterOptions{SslRedirect false,RequireSsl false,LoginCaseSensitive true,Users new[]{                new BasicAuthAuthorizationUser{Login HangfireSettings.Instance.LoginUser,                    // Password as plain textPasswordClear HangfireSettings.Instance.LoginPwd}}} )} }; app.UseHangfireDashboard(, options); IOC容器之Autofac Hangfire对于每一个任务(Job)假如都写在一个类里然后使用BackgroundJob/RecurringJob对方法(实例或静态)进行调用这样会导致模块间太多耦合。实际项目中依赖倒置原则可以降低模块之间的耦合性Hangfire也提供了IOC扩展其本质是重写JobActivator类。 Hangfire.Autofac是官方提供的开源扩展用法参考如下 GlobalConfiguration.Configuration.UseAutofacActivator(container); RecurringJob扩展 关于RecurringJob定时任务我写了一个扩展 RecurringJobExtensions,在使用上做了一下增强具体有两点 使用特性RecurringJobAttribute发现定时任务 public class RecurringJobService{[RecurringJob(*/1 * * * *)][DisplayName(InstanceTestJob)][Queue(jobs)]    public void InstanceTestJob(PerformContext context)    {context.WriteLine(${DateTime.Now.ToString(yyyy/MM/dd HH:mm:ss)} InstanceTestJob Running ...);}[RecurringJob(*/5 * * * *)][DisplayName(JobStaticTest)][Queue(jobs)]    public static void StaticTestJob(PerformContext context)    {context.WriteLine(${DateTime.Now.ToString(yyyy/MM/dd HH:mm:ss)} StaticTestJob Running ...);} } 使用json配置文件注册定时任务 [AutomaticRetry(Attempts 0)] [DisableConcurrentExecution(90)]public class LongRunningJob : IRecurringJob{    public void Execute(PerformContext context)    {context.WriteLine(${DateTime.Now.ToString(yyyy/MM/dd HH:mm:ss)} LongRunningJob Running ...);           var runningTimes context.GetJobDataint(RunningTimes);context.WriteLine($get job data parameter- RunningTimes: {runningTimes});               var progressBar context.WriteProgressBar();                  foreach (var i in Enumerable.Range(1, runningTimes).ToList().WithProgress(progressBar)){Thread.Sleep(1000);}} } Json配置文件如下 [{    job-name: Long Running Job,job-type: Hangfire.Samples.LongRunningJob, Hangfire.Samples,cron-expression: */2 * * * *,job-data: {RunningTimes: 300}}] 实现接口IRecurringJob来定义具体的定时任务这样的写法与Quartz.net相似可以很方便的实现Quartz.net到Hangfire的迁移。类似地参考了quartz.net使用job-data-map这样的方式来定义整个任务执行期间的上下文有状态的job. var runningTimes context.GetJobDataint(RunningTimes); 详细用法可以直接参考项目文档。 与MSMQ集成 Hangfire server在处理每个job时会将job先装载到事先定义好的job queue中比如一次性加载1000个job,在默认的sqlsever实现中是直接将这些job queue中的job id储存到数据库中然后再取出执行。大量的job会造成任务的延迟性执行所以更有效的方式是将任务直接加载到MSMQ中。 实际应用中MSMQ队列不存在时一定要手工创建而且必须是事务性的队列权限也要设置用法如下: public static IGlobalConfigurationSqlServerStorage UseMsmq(this IGlobalConfigurationSqlServerStorage configuration, string pathPattern, params string[] queues){    if (string.IsNullOrEmpty(pathPattern)) throw new ArgumentNullException(nameof(pathPattern));     if (queues null)   throw new ArgumentNullException(nameof(queues));       foreach (var queueName in queues){             var path string.Format(pathPattern, queueName);        if (!MessageQueue.Exists(path))                 using (var queue MessageQueue.Create(path, transactional: true))queue.SetPermissions(Everyone, MessageQueueAccessRights.FullControl);}    return configuration.UseMsmqQueues(pathPattern, queues); } 持久化存储之Redis Hangfire中定义的job存储到sqlserver不是性能最好的选择使用Redis存储性能将会是巨大提升(下图来源于Hangfire.Pro.Redis). Hangfire.Pro提供了基于servicestack.redis的redis扩展组件然而商业收费不开源。 但是有另外的基于StackExchange.Redis的开源实现 Hangfire.Redis.StackExchangegithub上一直在维护支持.NET Core项目实测稳定可用. 该扩展相当简单 services.AddHangfire(x {    var connectionString Configuration.GetConnectionString(hangfire.redis);x.UseRedisStorage(connectionString); }); Hangfire最佳实践 配置最大job并发处理数 Hangfire server在启动时会初始化一个最大Job处理并发数量的阈值系统默认为20,可以根据服务器配置设置并发处理数。最大阈值的定义除了考虑服务器配置以外也需要考虑数据库的最大连接数定义太多的并发处理数量可能会在同一时间耗尽数据连接池。 app.UseHangfireServer(new BackgroundJobServerOptions {    //wait all jobs performed when BackgroundJobServer shutdown.ShutdownTimeout TimeSpan.FromMinutes(30),Queues queues,WorkerCount Math.Max(Environment.ProcessorCount, 20) }); 使用 DisplayNameAttribute特性构造缺省的JobName public interface IOrderService : IAppService{    /// summary/// Creating order from product./// /summary/// param nameproductId/param[AutomaticRetry(Attempts 3)][DisplayName(Creating order from product, productId:{0})][Queue(apis)]    void CreateOrder(int productId); } 目前netstandard暂不支持缺省的jobname,因为需要单独引用组件System.ComponentModel.Primitives,hangfire官方给出的答复是尽量保证少的Hangfire.Core组件的依赖。 Hangfire在调用Background/RecurringJob创建job时应尽量使传入的参数简单. Hangfire job中参数包括参数值及方法名都序列化为json持久化到数据库中所以参数应尽量简单如传入单据ID这样才不会使Job Storage呈爆炸性增长。 为Hangfire客户端调用定义统一的REST APIs 定义统一的REST APIs可以规范并集中管理整个项目的hangfire客户端调用同时避免到处引用hangfire组件。使用例如Swagger这样的组件来给不同的应用方(Co /// summary/// Creating order from product./// /summary/// param nameproductId/param/// returns/returns[Route(create)] [HttpPost]public IActionResult Create([FromBody]string productId){    if (string.IsNullOrEmpty(productId))          return BadRequest();    var jobId BackgroundJob.EnqueueIOrderService(x x.CreateOrder(productId));BackgroundJob.ContinueWithIInventoryService(jobId, x x.Reduce(productId));    return Ok(new { Status 1, Message $Enqueued successfully, ProductId-{productId} }); } 利用Topshelf Owin Host将hangfire server 宿主到Windows Service. 不推荐将hangfire server 宿主到如ASP.NET appl署到windows service, 利用TopshelfOwin Host /// summary/// OWIN host/// /summarypublic class Bootstrap : ServiceControl{    private static readonly ILog _logger LogProvider.ForBootstrap();    private IDisposable webApp;     public string Address { get; set; }       public bool Start(HostControl hostControl)    {           try{webApp WebApp.StartStartup(Address);                   return true;}               catch (Exception ex){_logger.ErrorException(Topshelf starting occured errors., ex);            return false;}}                     public bool Stop(HostControl hostControl)    {        try{webApp?.Dispose();                      return true;}        catch (Exception ex){_logger.ErrorException($Topshelf stopping occured errors., ex);            return false;}} } 日志配置 从Hangfire 1.3.0开始Hangfire引入了日志组件LibLog,所以应用不需要做任何改动就可以兼容如下日志组件 SerilogNLogLog4NetEntLib LoggingLoupeElmah 例如配置 serilog如下LibLog组件会自动发现并使用serilog Log.Logger new LoggerConfiguration().MinimumLevel.Verbose().WriteTo.LiterateConsole().WriteTo.RollingFile(logs\\log-{Date}.txt).CreateLogger(); Hangfire多实例部署高可用 下图是一个多实例Hangfire服务部署 其中关于Hangfire Server Node 节点可以根据实际需要水平扩展. 上述提到过一个秒杀场景用户下单-订单生成-扣减库存实现参考github项目Hangfire.Topshelf. HF.Samples.Consumer 服务应用消费方(App/Webservice/Microservices等。) HF.Samples.APIs 统一的REST APIs管理 HF.Samples.Console Hangfire 控制面板 HF.Samples.ServerNode Hangfire server node cli 工具使用如下 echo offset dirclusterdotnet run -p %dir%\HF.Samples.ServerNode nodeA -q order -w 100dotnet run -p %dir%\HF.Samples.ServerNode nodeB -q storage -w 100 上述脚本为创建两个Hangfire server nodeA, nodeB分别用来处理订单、仓储服务。 -q 指定hangfire server 需要处理的队列-w表示Hangfire server 并发处理job数量。 可以为每个job queue创建一个hangfire实例来处理更多的job. 原文地址 http://www.cnblogs.com/ecin/p/6201262.html .NET社区新闻深度好文微信中搜索dotNET跨平台或扫描二维码关注
http://www.pierceye.com/news/223464/

相关文章:

  • 建网站域名注册后需要做seo是什么意思
  • 做系统正版win10系统下载网站安定网站建设
  • 代码怎么做网站网站建设合同 简单
  • 耐克官网网站设计做一个企业网站需要多少钱
  • 动易手机网站自己开发小程序要多少钱
  • 英迈思做的网站怎么样网站做m版
  • 通州设计网站建设城市宣传片制作公司
  • 南安网站设计网站创意
  • 建设部网站造价注册seo优化易下拉霸屏
  • 西安网站外包上海网站被查
  • 建简单网站高端建筑铝型材
  • wordpress 网站访问量高端建筑物图片
  • seo网站推广目的WordPress灯箱效果移动适配
  • 梅州正规的免费建站微信应用开发公司
  • 百度做网站教程网站建设与维护ppt
  • 化妆品网站建设方案做咩有D网站响网吧上不了
  • 网站 迁移房地产销售基础知识大全
  • 门户网站建设汇报材料网站开发与制作中期报告
  • 网站建设可以自己弄吗知乎做网站必须要服务器吗
  • 怎么制作自己的小程序专业seo整站优化
  • 做网站是干什么用的苏宁易购网站上的营销页面
  • 浪网站制作网站开发是无形资产
  • 做阿里巴巴网站可以贷款吗seo如何快速排名百度首页
  • 公司做网站都咨询哪些问题网站平台建设视频教学
  • 西安电子商务网站建设网站里面的链接怎么做
  • 郑州陆港开发建设有限公司网站58招商加盟项目
  • 徐州高端网站建设个人网站设计首页界面
  • 山西企业建站系统平台关键词 优化 网站
  • 地板网站建设方案有什么做美食的网站
  • 网站建设丶金手指专业网站幻灯片 字段