在使用Windows服务和SQL Server的OneWay WCF消息中排队

我需要实现WCF服务请求的排队机制。 该服务将被客户以单向的方式调用。 这些请求消息应该存储在SQL Server数据库中,并且Windows服务将消息排队。 处理请求的时间将是可configuration的。 如果在处理消息时出现错误,则需要重试100次,如果仍然失败,则需要终止。

还应该有一个机制来监测一天中进行的交易次数和失败次数。

质询

  1. 如果我使用MSMQ,则客户端可能已经将消息转发到队列,而不知道服务端点。 但是我正在使用SQL Server来存储请求消息。 客户端如何将请求发送到SQL Server?

  2. 解决scheme是否可行? 我们是否有任何文章/书籍解释如何实现上述?

  3. 在这种情况下,防止服务和客户端达到故障状态的步骤是什么?

  4. 将传入消息存储到数据库的最佳方法是什么?

  5. 实施重试机制的最佳方法是什么? 任何事情已经存在,所以我不必重新发明轮子?

  6. 有没有解释这个实现的书/文章?


笔记

  1. 消息的内容将是复杂的XML。 例如员工的差旅费用项目或员工名单。

  1. 将WCF请求logging到数据库

  2. 保证WCF服务中的数据处理

  3. MSMQ与SQL Server Service Broker的比较

  4. 是否有可能坚持,然后将WCF消息转发到目标服务?

  5. WCF 4路由服务 – 协议桥接问题

  6. https://softwareengineering.stackexchange.com/questions/134605/designing-a-scalable-and-robust-retry-mechanism

  7. 集成SQL Service Broker和NServiceBus

  8. 用户是否也可以在NServiceBus中发布/发送消息?

我是一名DBA,所以口味是我的回应,但是这就是我要做的:

  1. 如果您使用SQL 2005+,请使用Service Broker将消息存储在数据库中,而不是将其存储在表中。 你有这个排队机制,所以你可以摆脱MSMQ。 你也将有一个表,但它只是存储对话句柄(本质上,指向消息的指针)以及它尝试这个消息的次数。 最后,你会想要某种“死信箱”,在那里达到你的重试阈值的消息去。
  2. 在您的消息处理代码中,执行以下操作:
    • 开始交易
    • 从队列中接收消息
    • 如果重试计数大于阈值,请将其移至死信箱并提交
    • 增加此消息在表上的计数器
    • 处理消息
    • 如果处理成功,则提交事务
    • 如果处理失败,则在具有相同内容的队列上放置新消息,然后提交事务

请注意,没有任何计划的回滚。 Service Broker中的回滚可能很糟糕; 如果回滚5次而没有成功接收,队列将被禁用入队和出队。 但是,如果消息处理器在处理过程中死亡(即服务器崩溃),您仍然希望进行事务处理。

1.如果我使用MSMQ,则客户端可能已经将消息转发到队列,而不知道服务端点。

是的 – 但他们需要知道MSMQ端点才能将其消息发送到队列中…..

但是我正在使用SQL Server来存储请求消息。 客户端如何将请求发送到SQL Server?

客户端不会把他们的请求放入SQL Server – 这就是服务器上的服务所要做的。 客户端只需调用一个服务方法,那里的代码就会将请求存储到SQL Server表中。

2.解决scheme是否可行? 我们是否有任何文章/书籍解释如何实现上述?

当然,我没有看到任何大问题。 我现在唯一不清楚的是:客户怎么知道他们的结果? 他们是否需要从另一个服务或其他方面获得结果?

3.在这种情况下,防止服务和客户端到达故障状态的步骤是什么?

一如既往 – 只要确保服务代码捕获所有exception,并在内部处理它们,或者返回互操作的SOAP错误而不是.NETexception。

这听起来像你想要做的是类似于这样的:

在这里输入图像描述

在这种情况下,您可以在服务和服务使用者之间使用netMsmqBinding。

你不能从盒子里得到的唯一的东西就是重试。 但是,如果你使队列事务,那么这个function可以在你的服务代码中实现。

如果您的出列操作失败,消息将不会从队列中删除。 因此可以用于进一步的出队尝试。

但是,您需要实施重试尝试阈值代码,在尝试一定次数后会失败消息。

我会build议一个不同的方法来build议在这里。 如果可以的话,我会考虑引入一个消息框架,比如NServiceBus 。 它满足了你开箱即用的许多要求。 让我试着根据你的要求来解决这个问题。

该服务将被客户以单向的方式调用。

NServiceBus中的端点之间的所有通信都是一种方法。 NServiceBus使用的底层传输是MSMQ,与您的WCF方法非常相似,您的客户端正在与队列进行通信,而不是与特定的服务端点进行通信。

这些请求消息应该存储在一个SQL Server数据库中,并且一个Windows服务队列消息。

如果要将请求消息存储在数据库中,则可以configurationNServiceBus将发送到请求处理端点的所有消息转发到另一个“审计”队列,您可以使用该队列将其保留到数据库。 这还有另外一个好处,就是将您的应用程序逻辑从审计实施中分离出来。

处理请求的时间将是可configuration的。

NServiceBus允许您推迟何时发送消息。 通常情况下,消息通过总线实例的发送方法发送 – Bus.Send(msg)。 例如,您可以使用The Defer方法在未来某个时间发送消息。 Bus.Defer(DateTime.Now.AddDays(1),msg); 没有什么是你必须做的,NserviceBus将处理消息,一旦达到指定的时间。

如果在处理消息时出现错误,则需要重试100次,如果仍然失败,则需要终止。

默认情况下,只要消息离开队列,NServiceBus就会将消息logging在事务中。 这可以确保在发生故障时将消息回滚到始发队列。 在这种情况下,NServiceBus会自动尝试重新处理消息一个可configuration的次数。 默认值是5.你当然可以将它设置为任何你想要的,但是我不确定你为什么要把它设置为100.无论如何,NServiceBus使用这个设置来停止无限循环的自动重试。 达到限制后,邮件将被发送到错误队列,直到您解决导致该exception的任何问题,或者直到您决定将邮件推送回队列进行处理。 无论哪种方式,你放心,信息是永远不会丢失。

还应该有一个机制来监控一天中进行的交易次数和失败次数。

使用MSMQ作为交通工具的美妙之处在于性能监控可以在基础设施级别上实现。 你的应用程序如何执行,可以衡量他们坐在队列中的时间。 NServiceBus带有性能监视器,跟踪消息在队列中的时间长度,还可以添加内置在窗口中的perf mons来跟踪其他活动。 要监视错误,您只需检查错误队列中的消息数量即可。

NServiceBus的主要function之一是可靠性。 WCF只会为你做很多事情,然后你自己做。 这是很多代码,复杂性和坦率的极大的错误倾向。 我在这里描述的东西都是NServiceBus的所有标准function,我几乎没有用它可以做的所有其他的事情来抓住表面。 我build议你检查一下。