2012-03-14 91 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