【发布时间】:2019-07-07 21:33:28
【问题描述】:
我正在使用 EasyNetQ,需要重试原始队列上的失败消息。问题是:即使我成功地增加了 TriedCount 变量(在每个 msg 的正文中),当 EasyNetQ 在异常后将消息发布到默认错误队列时,更新后的 TriedCount 不在 msg 中!大概是因为它只是将原始消息转储到错误队列中,而没有消费者的更改。
更新后的 TriedCount 适用于进程内重新发布,但不适用于通过 EasyNetQ Hosepipe 或 EasyNetQ 管理客户端重新发布时。 Hosepipe 生成的文本文件没有更新 TriedCount。
public interface IMsgHandler<T> where T: class, IMessageType
{
Task InvokeMsgCallbackFunc(T msg);
Func<T, Task> MsgCallbackFunc { get; set; }
bool IsTryValid(T msg, string refSubscriptionId); // Calls callback only
// if Retry is valid
}
public interface IMessageType
{
int MsgTypeId { get; }
Dictionary<string, TryInfo> MsgTryInfo {get; set;}
}
public class TryInfo
{
public int TriedCount { get; set; }
/*Other information regarding msg attempt*/
}
public bool SubscribeAsync<T>(Func<T, Task> eventHandler, string subscriptionId)
{
IMsgHandler<T> currMsgHandler = new MsgHandler<T>(eventHandler, subscriptionId);
// Using the msgHandler allows to add a mediator between EasyNetQ and the actual callback function
// The mediator can transmit the retried msg or choose to ignore it
return _defaultBus.SubscribeAsync<T>(subscriptionId, currMsgHandler.InvokeMsgCallbackFunc).Queue != null;
}
我也尝试过通过Management API(粗略代码)重新发布自己:
var client = new ManagementClient("http://localhost", "guest", "guest");
var vhost = client.GetVhostAsync("/").Result;
var errQueue = client.GetQueueAsync("EasyNetQ_Default_Error_Queue",
vhost).Result;
var crit = new GetMessagesCriteria(long.MaxValue,
Ackmodes.ack_requeue_true);
var errMsgs = client.GetMessagesFromQueueAsync(errQueue,
crit).Result;
foreach (var errMsg in errMsgs)
{
var pubRes = client.PublishAsync(client.GetExchangeAsync(errMsg.Exchange, vhost).Result,
new PublishInfo(errMsg.RoutingKey, errMsg.Payload)).Result;
}
这可行,但只会再次发布到错误队列,而不是原始队列。另外,现阶段我不知道如何在消息正文中添加/更新重试信息。
我已经探索了this 库以向消息添加标头,但我看不到正文中的计数是否没有更新,如何/为什么更新标头中的计数。
有没有办法在不使用高级总线的情况下保留 TriedCount(在这种情况下,我可能会使用 RabbitMQ .Net 客户端本身)?
【问题讨论】:
标签: c# error-handling rabbitmq message-queue easynetq