本系列目录:Abp介绍和经验分享-目录

什么是后台作业系统

后台作业系统即BackgroundJob,从需求上讲,是一套基础设施,允许我们定义一个作业,在未来指定的某个时间去执行。

后台作业的一般场景:

  1. 如果某个业务逻辑很复杂,但又不是立即需要反馈结果给用户;
  2. 如果有个任务需要定时循环执行;
  3. 如果有个批量任务;
  4. 如果有个任务需要延后一段时间(在未来某个指定的时间)执行;

举几个典型例子:

  1. 订单在创建后30分钟未支付则自动取消并释放库存;
  2. 一个有几万甚至几十万粉丝的公众号需要同步粉丝信息到数据库;
  3. 某个活动开始前15分钟通知感兴趣的用户进行预热;
  4. 某个与友商合作的项目涉及结算,需要在每月指定日子出账单;
  5. 每天空闲时间段全量刷新缓存或者重建索引;

Abp的后台作业系统

Abp的后台作业系统有两个抽象概念:

  1. BackgroundWorker;
  2. BackgroundJob;

如果是第一次用Abp的后台作业系统,可以点击下面这个链接到官方文档看具体使用方法,这里主要介绍下这两个的特点和联系。

Background Jobs and Workers

BackgroundWorker

先说BackgroundWorker,BackgroundWorker其实就是基于一个TimerAbpTimer)设置时间间隔,在进程中定时执行。

在Abp核心模块AbpKernelModulePostInitialize方法的最后:

if (Configuration.BackgroundJobs.IsJobExecutionEnabled)
{
var workerManager = IocManager.Resolve<IBackgroundWorkerManager>();
workerManager.Start();
workerManager.Add(IocManager.Resolve<IBackgroundJobManager>());
}

我们看到可以通过Configuration.BackgroundJobs.IsJobExecutionEnabled控制是否启用workerManager,同时IBackgroundJobManager其实是个Worker(这里说的是JobManager,不是Job)。

BackgroundJob

IBackgroundJobManager继承了IBackgroundWorker,并且Abp默认实现的BackgroundJobManager也是基于Worker的机制,其基类是PeriodicBackgroundWorkerBase,静态构造方法中指定了每5秒拉取一次作业信息。

Abp.dll程序集中,Configuration.BackgroundJobs.IsJobExecutionEnabled启用时,默认用InMemoryBackgroundJobStore来存储作业信息。

在Abp核心模块AbpKernelModulePostInitialize方法的最开始RegisterMissingComponents(假如没有注册其他实现):

if (Configuration.BackgroundJobs.IsJobExecutionEnabled)
{
IocManager.RegisterIfNot<IBackgroundJobStore, InMemoryBackgroundJobStore>(DependencyLifeStyle.Singleton);
}
else
{
IocManager.RegisterIfNot<IBackgroundJobStore, NullBackgroundJobStore>(DependencyLifeStyle.Singleton);
}

如果Configuration.BackgroundJobs.IsJobExecutionEnabled未启用,则用NullBackgroundJobStore,如果启用,默认用的是InMemoryBackgroundJobStore,除非仅作演示用,否则InMemoryBackgroundJobStore没什么用,因为这些默认实现都没处理集群场景下Job的分布式执行和防止重复执行。

为便于我们在生产环境使用,看下面两个:

Abp框架提供了Abp.HangfireAbp.Quartz模块用于集成可用于集群化场景下的作业实现(防止重复执行等问题,Abp默认实现的IBackgroundWorkerManagerIBackgroundJobManager并未处理相关问题);

总结下

上面有点缺乏条理,总结下:

  1. Configuration.BackgroundJobs.IsJobExecutionEnabled不仅影响BackgroundJob的执行,同时也影响BackgroundWorker的执行;
  2. Abp默认实现的IBackgroundJobStore不支持集群环境下、分布式环境下的Job执行;
  3. Abp框架提供了Abp.HangfireAbp.Quartz模块支持集群环境下、分布式环境下的Job执行;

然后,还有个关于module-zero的小坑,提一下:

当我们项目中使用了module-zero模块,这个模块在业务数据库中实现了一个简单版本的IBackgroundJobStore

对,还是没处理重复执行的问题,而且你不用配置,只要用了module-zero,但没配置用Hangfire或者Quartz,这个机制就悄无声息的在跑!

这时候,job可能会重复执行,job可能去不同项目执行。

好多朋友都被这个坑过,引起的现象能让你怀疑人生!

module-zero的这个实现,个人认为是abp演示Notification机制的需要,其中有个分发机制是超出5人订阅,则转为Job进行分发。

明确一下不同Job配置实际上用的是哪个IBackgroundJobStore

  1. 什么都不配置,而且没依赖module-zero模块:IsJobExecutionEnabled默认是启用的,用的是基于内存的InMemoryBackgroundJobStore

  2. 什么都不配置,而且依赖了module-zero模块:用的是基于业务数据库的BackgroundJobStore,实体是BackgroundJobInfo,并且注册在AbpZeroDbContext中;

  3. 明确关闭IsJobExecutionEnabled:如果没依赖module-zero则用的是空实现NullBackgroundJobStore,不进行存储,否则作业信息可以入队,能在其他开启job执行的宿主项目上执行(假如共享了job代码所在的程序集);

  4. 明确配置依赖了Abp.HangfireAbp.QuartzIsJobExecutionEnabled启用的项目会执行,IsJobExecutionEnabled关闭的项目只入队不执行。

我们推荐的做法是(前提是核心的几个程序集共享,Abp框架并不是只能用于Web开发,也可以寄宿在控制台或win服务中,甚至桌面应用程序),所有iis站点关闭Job的执行,专门提供一个Windows服务启用IsJobExecutionEnabled

所有宿主程序都必须明确配置集成Abp.HangfireAbp.Quartz,哪怕你觉得这个项目和作业系统八竿子打不着!

所有宿主程序都必须明确配置集成Abp.HangfireAbp.Quartz,哪怕你觉得这个项目和作业系统八竿子打不着!

所有宿主程序都必须明确配置集成Abp.HangfireAbp.Quartz,哪怕你觉得这个项目和作业系统八竿子打不着!

我中招的那次,有怀疑过是不是AppDomain串了,甚至怀疑代码去不同进程串门了,怀疑人生。

最后差点忘说了,如果集成且启用了Hangfire,一定记得单独给他配个数据库,作业信息的扫描频率实在太高,据说Hangfire收费版支持存Redis,估计会好一点。

[2017-09-05]Abp系列——Abp后台作业系统介绍与经验分享的更多相关文章

  1. [2017-08-21]Abp系列——如何使用Abp插件机制(注册权限、菜单、路由)

    本系列目录:Abp介绍和经验分享-目录 Abp的模块系统支持插件机制,可以在指定目录中放置模块程序集,然后应用程序启动时会搜索该目录,加载其中所有程序集中的模块. 如何使用这套机制进行功能插件化开发? ...

  2. 基于DDD的现代ASP.NET开发框架--ABP系列文章总目录

    ABP相关岗位招聘:给热爱.NET新技术和ABP框架的朋友带来一个高薪的工作机会 ABP交流会录像视频:ABP架构设计交流群-7月18日上海线下交流会的内容分享(有高清录像视频的链接) 代码自动生成: ...

  3. ABP文档 - 后台作业和工作者

    文档目录 本节内容: 简介 后台作业 关于作业持久化 创建一个后台作业 在队列里添加一个新作业 默认的后台作业管理器 后台作业存储 配置 禁用作业执行 Hangfire 集成 后台工作者 创建一个后台 ...

  4. 基于DDD的现代ASP.NET开发框架--ABP系列之3、ABP分层架构

    基于DDD的现代ASP.NET开发框架--ABP系列之3.ABP分层架构 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ABP的官方网站:ht ...

  5. 基于DDD的现代ASP.NET开发框架--ABP系列之2、ABP入门教程

    基于DDD的现代ASP.NET开发框架--ABP系列之2.ABP入门教程 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ASP.NET Boi ...

  6. 点这里进入ABP系列文章总目录

    基于DDD的现代ASP.NET开发框架--ABP系列之1.ABP总体介绍 ABP是“ASP.NET Boilerplate Project (ASP.NET样板项目)”的简称. ASP.NET Boi ...

  7. [2017-09-04]Abp系列——为什么值对象必须设计成不可变的

    本系列目录:Abp介绍和经验分享-目录 这篇是之前翻备忘录发现漏了的,前阵子刚好同事又提及过这个问题,这里补上. 本文重点在于理解什么是值对象的不可变性. Abp的ValueObject以及EF的Co ...

  8. [2017-08-28]Abp系列——业务异常与错误码设计及提示语的本地化

    本系列目录:Abp介绍和经验分享-目录 前言 ABP中有个异常UserFriendlyException经常被使用,但是它所在的命名空间是Abp.UI,总觉得和展现层联系过于紧密,在AppServic ...

  9. [2017-08-16]ABP系列——QuickStartB:正确理解Abp解决方案的代码组织方式、分层和命名空间

    本系列目录:Abp介绍和经验分享-目录 介绍ABP的文章,大多会提到ABP框架吸收了很多最佳实践,比如: 1.N层 (复用一下上篇的图) 展现层(Personball.Demo.Web):asp.ne ...

随机推荐

  1. 我的js为什么会触发两次

    $(function() { $(".show").off("click").on("click",function(e){ e.preve ...

  2. Codeforces Gym101606 A.Alien Sunset (2017 United Kingdom and Ireland Programming Contest (UKIEPC 2017))

    2017 United Kingdom and Ireland Programming Contest (UKIEPC 2017) 寒假第一次组队训练赛,和学长一起训练,题目难度是3颗星,我和猪队友写 ...

  3. SYN攻击SYN Attack

    SYN攻击SYN Attack   SYN Attack是一种DOS攻击方式.它利用的是TCP协议的漏洞,攻击目标,使其不在响应网络请求.在TCP协议中,需要三次握手,才能建立TCP连接.在握手过程中 ...

  4. loj #110. 乘法逆元

    #110. 乘法逆元 内存限制:256 MiB时间限制:1000 ms标准输入输出 题目类型:传统评测方式:文本比较 上传者: 匿名 提交提交记录统计讨论测试数据   题目描述 这是一道模板题. 给定 ...

  5. 第4章 CentOS软件安装

    一.安装JDK 1.1 卸载旧版JDK 首先,在你的服务器上运行一下更新. yum update 然后,在您的系统上搜索,任何版本的已安装的JDK组件. rpm -qa | grep -E '^ope ...

  6. Linux下Shell的快捷键(转)

    下述所有命令在Linux/Unix的shell下有效,这里以bash为主.如有出入,以你自己的服务器为准.本文所指的Linux主要指RHEL/CentOS,Unix指的是FreeBSD,这也是Unix ...

  7. AngularJS的ng-class示例

    程序下载:https://files.cnblogs.com/files/xiandedanteng/angularJSRender.rar 代码: <!DOCTYPE HTML PUBLIC ...

  8. 百科知识 isz文件如何打开

    使用UltraISO可以打开

  9. LINUX下GDB反汇编和调试

    Linux下的汇编与Windows汇编最大的不同就是第一个操作数是原操作数,第二个是目的操作数.而Windows下却是相反. 1. 基本操作指令 简单的操作数类型说明.一般有三种. (1)马上数操作数 ...

  10. javascript之Ajax获取和设置标头

    XMLHttpRequest对象中与标头有关的方法: setRequestHeader(<header>,<value>)--用指定值设置标头. getResponseHead ...