- html - 出于某种原因,IE8 对我的 Sass 文件中继承的 html5 CSS 不友好?
- JMeter 在响应断言中使用 span 标签的问题
- html - 在 :hover and :active? 上具有不同效果的 CSS 动画
- html - 相对于居中的 html 内容固定的 CSS 重复背景?
我有多个现有应用程序通过 System.Messaging API 使用 MSMQ 发送和接收消息。队列通常是非事务性的,是 MSMQ 3 和 4 的混合。
接收应用程序现在处理有害消息,以至于在第一次出现任何异常时,消息被放入错误队列以进行人工干预。但事实证明,绝大多数手动干预只是简单地将消息移回主队列以进行另一次尝试,此时它会成功。因此,为了使该过程自动化,我想向接收器添加一个重试功能,以便将消息移回主队列给定的次数,每次之间有给定的延迟。
我不想重新发明轮子,而是想利用 MSMQ 开箱即用的任何东西以及任何流行的或最佳实践模式。为此,有很多关于 MSMQ 4 中对有害消息的额外支持。但它们似乎无法通过 .Net 轻松访问。此外,我可以找到使用它们的唯一引用是通过带有 MSMQ 绑定(bind)的 WCF。
如果不使用 WCF,任何人都可以提出任何模式或指向任何实现重试的示例吗?
最佳答案
我找不到一个单一的、流行的模式来做到这一点。但是在 System.Messaging 中探索了一下之后,我能够利用 Message 属性和 MSMQ 行为,我认为这是用最少的移动部件完成工作的合适方式。
这是我实现的。结果证明它相当简单和轻量级 - 代码不多且易于维护:
我创建了一个名为 RetryLevel 的对象,它具有三个属性:
整数顺序,
整数重试次数,
时间跨度延迟
接收应用程序的配置现在有一个 RetryLevel 列表。所以新特性基本支持n级重试。
然后我创建了一个名为 RetryInfo 的对象。这个对象有两个属性:
int尝试,
字符串源队列路径
RetryInfo 对象的一个实例被序列化并存储在每个最终被重试的 Message 的 Extension 属性中。这使我能够跟踪消息本身的当前重试状态,从而消除了维护单独的重试元数据存储的需要以及协调消息 Id、保持数据同步等的所有开销。
最后,我在接收器的配置中添加了一个等待队列路径。此队列是消息在“超时”时将被丢弃的地方。
因此,现在,当消息处理程序拒绝一条消息时,接收方将反序列化它的 RetryInfo,如果有的话,并查看(先前)尝试的数量以确定它已达到哪个配置的 RetryLevels。
然后接收者将消息的 TimeToBeRecieved (TTBR) 属性设置为 DateTime.Now 加上相应 RetryLevel 的延迟值。然后它将 AdministrativeQueue 属性设置为从 RetryInfo 的 SourceQueuePath 属性创建的队列,并将 Message 的 AcknowledgeType 设置为 AcknowledgeTypes.NegativeReceive。最后,它将消息放入等待队列。
从这里,MSMQ 监视消息的 TTBR。当超时时,MSMQ 将消息放回其管理队列属性中的队列中,该属性是消息最初来自的队列。如果消息继续被处理程序拒绝,它只会向上移动到 RetryLevels。
如果消息的尝试次数超过配置的 RetryLevels 上的所有 NumberOfRetries,则消息的 TTBR 属性设置为 TimeSpan.Zero,UseDeadLetterQueue 属性设置为 true,并且消息像任何其他重试一样被放入等待队列。然而,这一次,它立即超时,MSMQ 将它发送到等待队列的主机的系统死信队列 (DLQ),在那里可以手动处理它。
关于wcf - 在没有 WCF 的 MSMQ 中创建重试机制,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15115089/
是否可以重试网络客户端请求?在奇怪的情况下,我的应用程序在尝试连接到 xml Web 服务时会抛出错误,但如果我重试,它就可以正常工作。我希望它在抛出错误之前重试 2 次,除非有人有更好的解决方案:)
我在一本书中找到了这段代码片段: int ival; // read cin and test only for EOF; loop is executed even if there are oth
是否可以使用 for lop 来设置对象的条件。如果该条件未通过测试(if 语句),则更改条件直到它通过测试?这是我的伪代码尝试,但我怀疑它是否有效: for (int i = 0; i < myAr
我有以下问题。我的主要 Activity 由一个 ListView 组成,其中填充了从 Web 服务获得的数据。首次加载主要 Activity 时,以防无法从网络检索数据,我想显示一个带有 2 个按钮
我有微服务应用程序。为了协作,每个服务都使用异步消息传递。我知道,spring data jpa 默认使用乐观锁。但是如果这种锁定不是由用户调用,而是由另一个服务调用的方法(在我的示例中有验证服务,可
我希望能够在 F# 中编写一个计算表达式,如果它抛出异常,它将能够重试操作。现在我的代码看起来像: let x = retry (fun() -> GetResourceX()) let y = re
是否可以在 NServiceBus 版本 3.2.2 中禁用重试? 使用以下配置,可以禁用重试: 但当线程数设置为 20 时则不会。在这种情况下,消息会重试两次: 这看起来很像
我在 failed_jobs 上有多个失败的作业。我尝试重新排队 MaxAttemptsExceededException 但总是失败。如何重试那里的工作类型? 注意:每次我通过 php artisa
下面的 sproc 尝试向表中插入一行并生成一个随机 ID,用于在相应表上进行 PK。与随机生成的 ID 的冲突在 catch 块中处理,在那里再次重试/调用该过程。现在,这需要很长时间并导致死锁,因
我试图实现代码以使用“mocha-retry”重试失败的测试以下是示例。 describe(retries,' retries-',function () { var self = this;
我正在尝试通过 Azure 数据工厂将数据从 Azure 数据湖存储插入到 Azure 表。 Azure Data Lake 文件中的数据与最终 Azure 表接收器的架构相同。 ADF 管道包含从
是http.RoundTripper在 Go 中基于 HTTP 状态代码(例如 429)实现 http GET 请求重试机制的正确位置? 它在某种程度上“感觉正确”( Go Playground )并
使用 spring reactive WebClient,我使用了一个 API,如果响应状态为 500,我需要使用指数退避重试。但是在 Mono 类中,我没有看到任何以 Predicate 作为输入参
我一直在尝试编写 react native 的快速入门指南,但一直收到此错误 There appears to be trouble with your network connection. Ret
我正在尝试使用从我们心爱的堆栈溢出中获取的 Retry Monad: type RetryBuilder(max, sleep : TimeSpan) = member x.Return(
使用 spring reactive WebClient,我使用了一个 API,如果响应状态为 500,我需要使用指数退避重试。但是在 Mono 类中,我没有看到任何以 Predicate 作为输入参
我有一个由 C#.NET 4.0 开发的两层 Windows 窗体应用程序。在这个应用程序中,我读取文件内容并在数据访问层中创建实体列表,并将其返回到 GUI 层以在 GridView 中显示。在我当
如果有人问过这个问题,我深表歉意,但我已经做了很多搜索,但还没有找到与我的问题类似的问题。 在我的应用程序中,我有一个密码更改页面,如果某人是新用户或重置了他/她的密码,该页面就会触发。 问题是,一旦
想知道为什么我的 promise 正在解决但试图重试。 var getResultsStream = url => Rx.Observable.onErrorResumeNext( Rx.O
假设我有以下 Promise 链: var result = Promise.resolve(filename) .then(unpackDataFromFile) .then(tra
我是一名优秀的程序员,十分优秀!