2012-03-14 66 views
2

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

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

质询

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

  2. 该解决方案是否可行?我们是否有任何文章/书籍解释了如何实施上述内容?

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

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

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

  6. 是否有任何解释此实现的书/文章?


NOTES消息的

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

READING

  • Logging WCF Request to Database

  • Guaranteed processing of data in WCF service

  • MSMQ vs. SQL Server Service Broker

  • Is it possible to persist and then forward WCF messages to destination services?

  • WCF 4 Routing Service - protocol bridging issue

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

  • Integrating SQL Service Broker and NServiceBus

  • Can a subscriber also publish/send message in NServiceBus?

  • +0

    很难理解你想要做什么。你的客户正在调用一个服务,但也将请求放入SQL中?这没有多大意义。这些请求肯定会被服务使用。 – 2012-03-14 13:32:52

    +1

    嘿Lijo它更好地使用SQL“Servive Broker”,它能够很好地满足你的需求。我使用“ServiceBroker”.http://msdn.microsoft解决了类似的情况。com/en-us/library/ms166043(v = sql.90).aspx – sandeep 2012-04-11 10:45:20

    回答

    2

    1.如果我使用MS MQ,客户端可能会在不知道服务端点的情况下将消息转发到队列。

    是 - 但他们需要知道MSMQ端点为了送他们的消息队列.....

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

    客户端将不会把他们的请求到SQL Server - 这就是在服务器上服务会做。客户端只需调用服务方法,并且其中的代码将把请求存储到SQL Server表中。

    2.解决方案是否可行?我们是否有任何文章/书籍解释了如何实施上述内容?

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

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

    与往常一样 - 只要确保你的服务代码捕获所有异常,要么处理它们内部,或返回可互操作的SOAP错误,而不是.NET异常。

    +0

    谢谢。我对这些想法完全陌生。将传入消息存储到数据库中的最佳方法是什么? – Lijo 2012-03-15 13:30:02

    +0

    @Lijo:完全取决于消息.....什么构成了你的消息?一些字符串?一个非常复杂的XML结构? – 2012-03-15 13:30:52

    +0

    复杂的XML。例如员工的差旅费用项目或雇员列表 – Lijo 2012-03-15 13:32:54

    2

    这听起来像你想要做的是与此类似:

    enter image description here

    在这种情况下,你可以在你的服务,你的服务消费者之间使用netMsmqBinding。

    你不会从盒子里得到的唯一东西就是重试。但是,如果您将队列交易,那么可以在您的服务代码中实现此功能。

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

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

    +0

    谢谢。但是,我正在寻找稍有不同的方案 - 将消息存储到数据库。我已经更新了这个问题。你能否提供更多的见解? – Lijo 2012-03-15 13:56:44

    +0

    我很抱歉,但您的问题仍然没有意义。我看不出为什么你必须将这些消息存储在数据库中,然后让一个windows服务将它们放在一个队列中。同时您有客户致电服务。它不会一起挂。也许你可以创建一个新的问题来描述你的业务需求,我们可以从那里开始。 – 2012-03-20 08:13:38

    3

    我是一名DBA,让我的口味我的反应,但这里是我会怎么做:

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

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

    +0

    感谢死信队列的概念 – Lijo 2012-03-19 14:51:05

    1

    我会建议一个不同的方法来建议这里的。如果您能够,我会考虑引入消息框架,如​​。它满足您开箱即用的许多要求。让我试着根据你的要求来解决这个问题。

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

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

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

    如果你想存储在数据库中的请求消息,那么你可以配置NServiceBus发送到您的请求处理端点的所有邮件转发到其他“审计”的队列,你可以用它来坚持到数据库中。这有助于将您的应用程序逻辑从审计实施中分离出来。

    请求处理的时间是可配置的。

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

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

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

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

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

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

    +0

    谢谢。看起来有希望。如果我还有其他问题,我会通知你。 – Lijo 2012-03-19 13:40:33

    +0

    但是,我不能在我的项目中使用它,因为它需要用WCF开发。 – Lijo 2012-03-19 14:52:27

    +0

    如果需要,您仍然可以在客户端使用WCF。让处理消息的服务器组件公开一个WCF端点,供客户端进行交互。然后你可以使用NServiceBus来完成消息的实际处理。下载中有一个示例应用程序,显示了如何实现这一目的的示例。无论哪种方式,祝你好运。 – stephenl 2012-03-19 22:32:50