功能说明

LongIntervalRetries是基于Quartz.Net的一个长时间间隔重试的类库,其主要解决何时执行以及执行结果反馈的问题。

产生的原因

简单的说,我们提供了一系列的API供第三方调用,但因为实际API对应的业务处理时间较长,所以为了增加吞吐量,实际的业务逻辑并没包含在API服务器,而是分布在了不同的服务器上进行处理,在业务处理结束后,再通过调用第三方提供的回调Url通知处理结果,为了保证回调正确,那么我们需要有这么一个策略:如果回调失败,我们需要在指定时间间隔之后再次回调,如此反复直至回调成功或者达到重复次数上限。上述回调方案是不是很熟悉?嗯,好吧,直白的讲,回调这一部分我们借鉴(抄袭)了支付宝支付时的回调方案,所以我们要解决的,就是通过代码来实现回调这部分的业务场景,于是也就有了LongIntervalRetries

为什么不使用Polly

Polly是.NET基金会下的弹性和瞬态故障处理库,其解决的问题天然符合我们回调的业务场景,但为什么在此处却不被采用呢,原因如下:

  • Polly的重试机制是个短时间内的机制,在其重试机制时间内,当前Task一般是通过await阻塞的,而对于我们的场景来说,这明显是不合适的,我们的场景并不应该发生在当前线程内
  • Polly并不支持程序重启时的重试恢复,这一点在我们的业务场景中及其重要,总不能服务器重启后,我们还没回调成功的业务就全部丢了吧

设计思路及演变

一开始我们的设计思路非常简单,就是如何定时触发回调这个业务代码,但之后发现,为什么我们要仅限于回调呢?回调只是一个业务场景,但我们完全有可能有其它业务场景,恰恰我们也的确存在这样的业务场景,我们需要向第三方服务商进行一些请求,该请求同样耗时较长,该场景是不是很熟悉?只不过与我们作为服务商不同,该服务商居然没提供回调方案,它需要我们自己定时去回调!而同样是这个第三方,其业务请求参数具有相当的定制性,其需要我们预先做很多业务性的预处理,也就是需要做一些顺序性的工作后,我们才能得到完整的请求参数。

于是我们的设计思路开始调整,最终得出该封装应当具备的功能点:

  • 其内部应该封装掉如何定时触发这个功能
  • 其应该具备同时支持多种业务策略(策略模式)
  • 其应该允许设置什么时候来触发要执行的策略
  • 其应该支持服务启动时自动恢复未结束任务的能力
  • 其应该具备最终执行结果通知的能力

为什么会考虑基于Quartz.Net

无论是定时触发,还是业务策略,以及设置触发时间,这些都很明显的具备Job特性,而Quartz.Net本身就是一个Job类库,而且其本身允许进行并发线程数量设置,如果基于它,明显我们可以不用考虑线程相关的问题,这可以省掉我们很大的工作量

类库相关

该类库在github上的地址为:https://github.com/fdstar/LongIntervalRetries

该类库目前为v1.0.0版本,其nuget地址为:https://www.nuget.org/packages/LongIntervalRetries/

快速使用

此处仅是简单的代码示例,后续会有详细的使用说明

首先我们需要声明Job

    public class SomeJob: IJob
{
public virtual Task Execute(IJobExecutionContext context)
{
return Task.FromResult(1);//默认LongIntervalRetries是通过Job是否产生异常来判断是否执行成功的
}
}

然后我们可以将这个Job注册到LongIntervalRetries,同时设置重试策略,以及注册事件监控执行结果,完整的示例如下

var retry = new StdRetry();
//声明并注册重试规则
string simpleRuleName = "SimpleRepeatRetryRule";
var simpleRepeatRule = new SimpleRepeatRetryRule(simpleRuleName, 5, TimeSpan.FromSeconds(2));
retry.RuleManager.AddRule(simpleRepeatRule);
var registerInfo = new RetryJobRegisterInfo
{
//指定要采用的重试规则,如果不设置,则默认使用已注册的第一项
UsedRuleName = simpleRuleName,
//需要传递给IJob的上下文数据
JobMap = new Dictionary<string, object>
{
{"SomeKey","SomeValue" }
},
//开始执行时间,如果不指定则表示立刻执行
StartAt = DateTimeOffset.UtcNow.AddSeconds(3),
};
//注册要执行的Job
retry.RegisterJob<SomeJob>(registerInfo);
//注册每次Job执行后的通知事件
retry.RegisterEvent<SomeJob>(e =>
{//Some code
});
retry.Start();//启动Quartz服务
//启动服务后仍可以RegisterJob、RegisterEvent

【LongIntervalRetries】让我们来实现支付宝的异步回调方案的更多相关文章

  1. 服务器收不到支付宝notify_url异步回调请求的问题 支付宝notify 异步通知与https的问题

    需确认页面是http还是https,如果是https,那么需要安装ssl证书,证书要求有如下:要求“正规的证书机构签发,不支持自签名”. 然后赶快,按照支付宝,宝爷的要求,去自检了一下自家的证书,下面 ...

  2. 服务器收不到支付宝notify_url异步回调请求的问题排查

    小背景 最近在调整支付宝支付的功能时发现,不能够正常接收支付宝付款成功之后的回调通知了,从代码到配置最后到服务器配置都排查了一遍,最终发现问题原因竟然是因为我们的回调地址notify_url是http ...

  3. 通知url必须为直接可访问的url,不能携带参数 异步接收微信支付结果通知的回调地址 不能携带参数。 回调地址后是否可以加自定义参数 同步回调地址 异步回调地址 return_url和notify_url的区别

    [微信支付]微信小程序支付开发者文档 https://pay.weixin.qq.com/wiki/doc/api/wxa/wxa_api.php?chapter=9_7 通知url必须为直接可访问的 ...

  4. 支付回调地址 同步回调地址 异步回调地址 return_url和notify_url的区别

    [微信支付]JSAPI支付开发者文档 https://pay.weixin.qq.com/wiki/doc/api/jsapi.php?chapter=9_16&index=10 退款结果通知 ...

  5. node 异步回调解决方法之yield

    先看如何使用 使用的npm包为genny,npm 安装genny,使用 node -harmony 文件(-harmony 为使用es6属性启动参数) 启动项目 var genny= require( ...

  6. c#线程之异步委托begininvoke、invoke、AsyncWaitHandle.WaitOne 、异步回调

    单靠自己看书学总是会走很多弯路,任何人也不列外,有些时候自己遇到的很多问题,其它别人在很久之前也可能遇到过,上网查查可以走很大捷径,对自己的学习有很大帮助,刚开始弄线程这块,一开始只是看书,很多东西都 ...

  7. Android异步回调中的UI同步性问题

    Android程序编码过程中,回调无处不在.从最常见的Activity生命周期回调开始,到BroadcastReceiver.Service以及Sqlite等.Activity.BroadcastRe ...

  8. java 中的异步回调

    异步回调,本来在c#中是一件极为简单和优雅的事情,想不到在java的世界里,却如此烦琐,先看下类图: 先定义了一个CallBackTask,做为外层的面子工程,其主要工作为start 开始一个异步操作 ...

  9. C“中断” 与 JS“异步回调” 横向对比

    在底层C语言中,有一个非常重要而特别的概念,叫做“中断”.用比喻来说,我正在写着博客,突然我妈打个电话过来,我就离开了键盘去接电话了,然后写博客就中断了,我聊完电话回来再继续写.乍一听似乎并没有什么大 ...

随机推荐

  1. SVN概述

    ----------------------siwuxie095                                 SVN 概述         1.SVN 即 Subversion 的 ...

  2. 【校招面试 之 剑指offer】第10-3题 矩阵覆盖问题

    题目:我们可以使用2✖️1的小矩形横着或者竖着去覆盖更大的矩形.请问用8个2✖️1的小矩形无重叠地覆盖一个2✖️8的大矩形,共有多少种方法? 分析:当放第一块时(假定从左边开始)可以横着放,也可以竖着 ...

  3. Dom对象总结介绍&事件介绍&增删查找标签

    1.dom有5个属性,属性内容如下 下面开始介绍Dom属性,一共有5个属性 1.document object:文档对象 2.element object:标签对象 3.test object:文本对 ...

  4. js 放在公共头部 子页面引用js 失效问题

    先回忆一下二者的区别(对于此篇文章而言,二者在用法上没有区别) jsp:include是先编译一下included.jsp文件,然后再包含 先编译,后包含 @ include是先把文件包含就来,然后统 ...

  5. win7安装SQL2005出现29506错误

    解决方法: 假设下载的文件名为SQLServer2005_SSMSEE.msi ,并且放在F盘根目录下, 新建一个文本文件,输入msiexec /i F:\SQLServer2005_SSMSEE.m ...

  6. SQL2000清除SQL日志

    1.打开查询分析器,输入命令DUMP TRANSACTION 数据库名 WITH NO_LOG2.再打开企业管理器--右键你要压缩的数据库--所有任务--收缩数据库--收缩文件--选择日志文件--在收 ...

  7. 禁用xampp的ssl功能

    按照Disable SSL on XAMPP for Windows文章里讲解的步骤如下: 1 以管理员身份启动XAMPP控制面板,点击Config按钮打开httpd.conf 分别注释171,539 ...

  8. BZOJ1222 [HNOI2001]产品加工 - 动态规划- 背包

    题解 怎么看都不像是个背包,直到我看了题解→_→, 第一次碰到这么奇怪的背包= = 定一个滚动数组$F_i$, $i$表示机器$a$用了$i$的时间, $F_i$表示机器$b$用了$F_i$的时间, ...

  9. lib文件反汇编

    运行vc命令行,输入:dumpbin /disasm xxx.lib > test.txt lib就是obj文件打包起来的,可以用lib.exe解出来,下面是vc环境下的操作,其他环境,看命令行 ...

  10. 使用 EWS(Exchange Web Service)协议读取邮件、发送邮件

    问题: 公司之前可以通过POP3协议收发邮件,因而在SoapUI中用JavaMail可以读取邮件,后来配置了Office 365,POP3协议端口不再开放,邮件全部读取失败,报login timeou ...