功能说明

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. Py2exe——将python程序变成windows下可执行的exe

    一.安装Py2exe 二.定义一个目录,把你的Python文件放在下面,如为AddFileRandom.py文件 然后新建一个go.py文件,放于相同目录下,内容为: from distutils.c ...

  2. php不重新编译,安装未安装过的扩展,如curl扩展

    假设我们的之前的php安装于/data/php下. 1.找到之前安装的PHP源码包,把它重新解压出来,进入到要安装的扩展目录. > cd /data/php-5.6.11/ext/curl (* ...

  3. session总结

    1.session是服务器端内存中的一块存储空间. 2.不同的浏览器窗口对应着不同的Session对象,两者的关系由Session ID来进行维护. 3.session的生命周期是以最后一次请求到达服 ...

  4. windows下用tcc编译Lua

    脚本来源:Demon's Blog,http://demon.tw/software/compile-lua-with-tcc.html 版权归原作者所有 使用方法: 1.下载tcc编译器,本文解压目 ...

  5. css设置超出部分文档隐藏(在table标签中不好使解决方案在下)

    css设置: .text-over{overflow: hidden;white-space: nowrap;text-overflow: ellipsis;cursor: pointer} div设 ...

  6. maven 发布打包部署 命令

    一.配置好jdk 二.下载安装maven http://maven.apache.org/download.cgi 三.添加环境变量 1. 添加 M2_HOME 和 MAVEN_HOME 环境变量到 ...

  7. Scrum 团队成立 -- 软件工程

      团队项目选题  : 金融工具:复利计算与投资记录项目继续升级,开发定位明确.功能专注的工具类软件 团队队员 : 蔡舜 , 林宇粲 , 王昕明 , 卢晓洵 团队目标 : 不断完善 团队口号 : 永不 ...

  8. iOS.Dev.Support.MultiVersions

    如何利用target conditionals和availabilty 如何来区分平台iOS OR Mac “When building for iOS the deployment target i ...

  9. Java数据结构和算法(七)B+ 树

    Java数据结构和算法(七)B+ 树 数据结构与算法目录(https://www.cnblogs.com/binarylei/p/10115867.html) 我们都知道二叉查找树的查找的时间复杂度是 ...

  10. win7安装qt5 纯记录 水文

    去qt官网下载http://www.qt.io/看见download就点进去看看吧 目前的下载地址路径是http://www.qt.io/download-open-source选择Offline I ...