1. 程式人生 > >biztalk中的傳送埠產生異常及處理(下)

biztalk中的傳送埠產生異常及處理(下)

導讀:
  一、 傳送埠返回NACK後的處理方法
  1、掛起的Orchestration是否可恢復?
  不管是一般傳送埠或是web型別的傳送埠,一旦接收到NACK訊息,Orchestration丟擲異常後,如果沒有設定scope捕獲異常並處理,將導致Orchestration服務例項被掛起。
  這樣掛起的Orchestration服務例項是否可恢復呢?
  如果Orchestration沒有設定Exception Handler,傳送埠的失敗會導致兩個掛起的服務例項:一個是傳送埠的服務例項,一個是Orchestration的服務例項。
  下面分別測試一下兩種傳送埠在未設定scope掛起後是否能被恢復。
  1.1. 一般傳送埠錯誤導致掛起的Orchestration
  一般的傳送埠,傳送一條資料插入到sql server,如果是因為插入了重複鍵導致了傳送訊息失敗,將產生兩個掛起的服務例項。
  

  
  Figure 3. 物理髮送端口出錯後產生的兩個掛起的服務例項
  
  圖中上面一個Messaging型別的服務就是sql的傳送埠服務例項。
  下面那個是Orchestration服務例項。
  
  在sql server把重複鍵的那條記錄刪除後,測試是否可以恢復這兩個服務例項。分別在兩個服務例項上點選右鍵,選“Resume Instance”。
  測試發現:
  sql的傳送埠服務例項可以被恢復,恢復後資料被寫入資料庫,掛起的sql的傳送埠服務例項完成,不再掛起。
  Orchestration服務例項進行恢復後,依然丟擲同樣的錯誤,服務例項再次被掛起。不管恢復多少次Orchestration,總是會丟擲同樣的異常。
  1.2. Web型別傳送埠錯誤導致的Orchestration
  經過測試,web型別的傳送埠錯誤導致颳起的Orchestration,跟一般埠錯誤導致掛起的Orchestration一樣,也是傳送埠在外部條件恢復後可以resume,Orchestration卻不再能resume。
  
  測試結果:

  似乎有這樣的規律,orchestration收到了NACK的訊息導致掛起,這樣掛起的orchestration都不能恢復。
  分析原因可能是因為第一個NACK訊息已經被Orchestration接收,再次resume執行Orchestration,這個NACK訊息再次導致Orchestration丟擲異常,所以,不管恢復多少次Orchestration,總是會丟擲同樣的異常。
  不知道是否有什麼方法能把這個NACK訊息從掛起的Orchestration例項中去掉
  
  2、如何處理髮送端口出錯的情況
  從上面的測試可以看到,一旦傳送埠返回了NACK後,即使導致傳送端口出錯的外部條件恢復後,傳送埠可以resume,但是掛起的Orchestration再也不能恢復了。
  下面設計一個處理這種情況的方法。
  設計一個簡單場景,Orchestration從A系統接收訊息,做必要的轉換後,把訊息通過Port_ConsumeWS web埠傳送到Web services,Orchestration接收到WS返回的訊息,把返回訊息通過Port_2埠傳送到B系統。
  

  
  Figure 4. 傳送端口出錯後Orchestration異常處理
  
  2.1. 異常處理並告知源系統出錯
  傳送形狀設定scope用以捕獲傳送埠返回的異常。
  Exception Handler的Exception Object Type 設定為System.Web.Services.Protocols.SoapException(可能需要引用System.Web.Services.dll程式集)。
  Exception Handler的Exception Object Name設定為e,表示捕獲到的一場物件。
  
  在ConstructMessage_2訊息構造形狀中構造一個反映SoapException異常的訊息Message_Fault(XmlDocument型別的訊息)。
  Message_Fault = new System.Xml.XmlDocument();
  Message_Fault.LoadXml(e.Detail.InnerXml);
  e.Detail.InnerXml 就是NACK的訊息實際內容。
  最後把這個NACK訊息返回給A系統,告訴A系統傳送訊息失敗。這個Orchestration然後正常結束。
  A系統接到失敗訊息後,可以在系統內部設計一個機制,比如間隔一定時間後,再次傳送同樣的訊息。
  2.2. 路由失敗訊息
  前面Orchestration異常處理後,Orchestration把失敗訊息傳送到A系統,之後Orchestration正常結束了。但是傳送埠返回NACK後,物理髮送埠本身也被掛起,如果不加處理,掛起的傳送埠服務例項一直會被掛著,可以通過路由失敗訊息的機制把傳送埠失敗的訊息路由到某一個資料夾,作為垃圾收集站,同時消除裡掛起的傳送埠例項。
  2.2.1. 設定允許路由失敗的訊息
  需要允許傳送到web services的SOAP傳送埠導致的失敗訊息可以路由。
  在biztalk administrator中檢視這個物理埠的屬性,然後在Transport Advanced Options 中設定“Enable routing for failed messages”。
  
  
  Figure 5. 傳送埠設定為允許路由失敗的訊息
  
  2.2.2. 新建收集失敗訊息的傳送埠
  在biztalk administrator中新建一個File的傳送埠,用來訂閱失敗的訊息,都發送到一個資料夾。
  設定傳送埠的屬性。
  設為File型別的傳送埠,路徑指向設定好的資料夾。
  埠的Filters設定如下:
  
  
  Figure 6. 收集失敗訊息傳送埠的訂閱設定
  
  Filter屬性用來定義傳送埠訂閱訊息的條件。
  ErrorReport.ErrorType==FailedMessageAnd
  ErrorReport.OutboundTransportLocation==http://biztalkr2:81/WSTest/Service1.asmx
  這樣的條件表示傳送埠訂閱失敗的訊息,並且是發往“http://biztalkr2:81/WSTest/Service1.asmx”的失敗訊息。
  
  3、總結
  通過異常處理和路由失敗訊息,可以把傳送埠產生異常導致的服務例項的掛起進行處理,結果是源系統可以獲得訊息未被成功傳送的通知,從而可以採取相應的處理辦法,或者定時重發,或者通過別的渠道處理訊息等等。biztalk這邊異常被處理,掛起的服務也都得到處理。
  如果在傳送形狀前面還有業務流程併產生了作用,捕獲異常後可能還需要做相應的補償,這裡沒有討論補償的問題。
  另外,這個方案應該不是最佳方案,因為A系統已經把訊息傳送到biztalk系統,如果在導致異常的外部條件已經恢復後,能夠在biztalk這個部分就能實現resume那是最理想的。

本文轉自
http://www.cnblogs.com/chnking/archive/2007/12/13/993702.html