[MQ]QueuedComponent設計時瞭解事項[MQ] (轉)

amyz發表於2007-08-15
[MQ]QueuedComponent設計時瞭解事項[MQ] (轉)[@more@]

Queued Component設計時瞭解事項:namespace prefix = o ns = "urn:schemas--com::office" />

摘要:本章概述了設計MSMQ佇列時需要了解的9個事項。

4.1. 公有佇列和私有佇列

把一個COM+應用設定為排隊之後,本地的MSMQ佇列中將會增加7個佇列:一個公有佇列,6個私有佇列。

公有佇列,它的名字和COM+應用的名字相同。它透過活動目錄通告它的存在。

  6個私有佇列中,序號為0-4的5個重試佇列,一個死信佇列。

4.2. COM+應用必須手動啟動

為QCMsg接收任何訊息的QCMsg的父應用程式必須是執行的。這一點很關鍵。為確信你的應用程式正在執行,在元件服務中在它上面簡單地右擊並選擇Start。

注意,即使應用程式不在執行,客戶仍能透過記錄器傳送訊息---它們只是不拾取並給QCMsg的一個新例項,直到應用程式下一次執行。

應用程式需要明確地執行或者另外使用COM+管理啟動,這也許看起來很奇怪。

正是QC和MSMQ的非同步的、監視的屬性,使明確地啟動成為必須。

4.3. 禁止

出現過下面情況的話,那麼你可以採用禁止安全的策略。

現象:

我的機器沒有聯網的情況下,我執行QCClientVC程式,QCCompVC佇列元件。這時候,QCCompVC元件沒有被呼叫,實際上訊息佇列的佇列à事務性死信訊息中出現了這些訊息。錯誤原因,上面寫的是“簽名無效”。

 

同時,在應用程式日誌中出現這樣的日誌:

事件型別錯誤

事件來源:  AutoEnrollment

事件種類

事件 ID:  15

描述:

本地系統 的自動證書註冊聯絡 Active Directory (0x8007054b) 失敗。  指定的域不存在,或無法聯絡。

  將不會註冊。

 

有關更多資訊,請參閱在 的幫助和支援中心。

 

和你指定的NT域拓撲相伴的安全設定和其他管理問題給這個處理增加了另一個更復雜的層。為了完全去除安全層,轉到Tomo_QC_Demo的COM+應用程式的屬性頁,並在Security屬性標籤上單擊,調整設定使Authentication level for calls設定為None,如下圖所示:

 

 

如果你的測試機器2000處於Workgroup工作組,那麼必須應用同樣的策略---禁止安全。因為在這個模式下,活動目錄服務不能用來提供驗證。用於建立的呼叫或使用你的佇列元件將失敗。

 

4.4. 事務佇列

預設地,當你為一個COM+應用程式單擊Queued核取方塊時,你獲得了七個事務佇列。

當COM+重複地試圖投遞一個事務的訊息給一個崩潰的呼叫SetAbort()或者涉及一些其他失敗的RM物件,它在有限的佇列中移動----從最低到最高。最終,如果訊息不能被投遞,它在死訊息佇列中結束(或者我們自己定義一個“異常類”,讓COM+播放給我的異常類)。

注意,七個佇列中的每一個佇列都是事務的,但當未能投遞它時,從一個佇列向更高數字佇列的訊息的移動並不意味著它是一個事務佇列的一部分。透過六個佇列的向上移動並最終達到一個死訊息佇列是一個COM+的約定---不是事務或MSMQ的約定。

重試次數是單一的----不是累積的。換句話說,在第一個失敗上等待60秒後,COM+在第二個失敗後等待60秒等等。

所以,你不要相信一個訊息僅僅會被投遞一次。

你也可以不使用事務佇列。這些佇列不保證投遞,可以確信,訊息可能完全丟失。

 

4.5. 異常類

如果一個佇列方法呼叫未能投遞時,你想被明確地通知,那麼你僅僅需要宣告一個異常類(exception class)。

如果你不想窺視一個佇列並分析失敗的訊息,那麼你可以請求COM+播放失敗的方法呼叫給你的異常類。你的異常類所需要做的是,簡單地實現所討論的包含失敗方法呼叫的佇列介面。

換句話說,你能如此編寫你的異常類以致在某種意義上它是接收器物件的有害孿生兄弟。如果方法呼叫未能播放給接收器物件,那麼你的異常類將代替地接收方法呼叫,正好像它是最初的想到達的目標物件。

 

4.6. 釋放Recorder物件的重要性

呼叫佇列元件的人A根本不必知道它正在使用的元件是一個佇列元件。A呼叫::CoGet為元件檢查。這裡,A找到的是一種佇列元件物件的Recorder物件。

一旦A得到Record物件,它就能呼叫QCMsg方元件。

當Recorder物件被釋放後,資料將被傳送到本地的MSMQ佇列中。當客戶機同伺服器相聯絡時,MSMQ就把資料送到伺服器進行處理。

 

換句話說,只有Recorder物件被立即釋放,這個請求才會真的被傳送到MSMQ佇列。否則,將等待中。

所以,A中就是每一次請求QCMsg都重新建立一次Recorder物件,程式碼如下所示:

  for (itPath = m_oUGSystemProfile.m_listQCInfo.begin(); 

   itPath != m_oUGSystemProfile.m_listQCInfo.end(); 

   itPath ++)

  {

  IInteraction *pInteraction = NULL;

  HRESULT hr = ::CoGetObject((*itPath),

    NULL,

    IID_IInteraction,

    (void**)&pInteraction);

 

  if(pInteraction != NULL)

  {

  pInteraction->XXXXXXXXX;

  pInteraction->Release();

  pInteraction = NULL;

  }

  else

  {

  …錯誤處理

  }

  }

4.7. 沒有COM+代理的結果

如果,請求的伺服器名為一個你沒有安裝佇列元件COM+代理的伺服器,那麼將會報告如下錯誤:

 

事件型別:  錯誤

事件來源:  COM+

事件種類:  (115)

事件 ID:  4808

描述:

訊息佇列 返回一個意外錯誤。MQPathNameToFormatName : 佇列不存在,或者您沒有足夠來執行此操作。

伺服器應用程式 ID: {BF966AC5-BDA0-4869-9430-BA3B0325D425}

伺服器應用程式例項 ID:

{F277BBD0-BB06-4E4F-B633-2ABE09FFBB01}

伺服器應用程式名: Tomo_QC

錯誤程式碼= 0xc00e0003 :

COM+ 服務內部資訊:

: d: tcomcom1xsrccomsvcsqcmsmqrtmsmqrt.cpp, 行: 746

Comsvcs.dll 檔案版本: ENU 2001.12.4414.46 shp

 

有關更多資訊,請參閱在 asp 的幫助和支援中心。

 

4.8. 重試的次數

根據

ms-help://MS.MSDNQTR.2002OCT.1033/cossdk/htm/pgservices_queuedcomponents_6l4j.htm

的說明:

The first retry queue. A message can be retried three times on this queue before being moved to the back of the second retry queue.

其他的retry佇列也有相同的屬性:進入一個retry佇列,在移到下一個佇列之前,會重試三次。

那麼就是5個retry佇列,總共rertry15次。

再加上最開始的一次,在到達Dead Queue之前,會傳送訊息16次。

4.9. Exception Class Component的製作

首先,一定要實現兩個介面:

n  你的佇列元件的要的那個介面;

n  COMSVCS的IPlaybackControl介面

VB中的例子程式碼為:

Implements IPlaybackControl

Implements IInteraction

 

Private Sub IInteraction_DisplayMessage(ByVal strMessege As String)

 

  Dim oTrace As New Tracer 

  oTrace.Trace strMessege & CStr(Time())

  Set oTrace = Nothing

End Sub

 

Private Sub IPlaybackControl_FinalClientRetry()

 

  Dim oTrace As New Tracer 

  oTrace.Trace "IPlaybackControl_FinalClientRetry" 

  Set oTrace = Nothing

End Sub

 

Private Sub IPlaybackControl_FinalServerRetry()

 

  Dim oTrace As New Tracer 

  oTrace.Trace "IPlaybackControl_FinalServerRetry" 

  Set oTrace = Nothing

End Sub

其次,在佇列元件介面的屬性頁à高階的“佇列異常類”編輯框中輸入這個Exception Class Component的ProgID或者ClassID。如下圖所示:

 

建議,把這個Exception Class Component也放入COM+。

這樣,當以下兩種情況發生時,這個元件將被呼叫:

第一種:ServerError

伺服器端的呼叫遭遇崩潰,導致訊息不斷被retry,直至送到dead queue。這時候,ECC的IPlaybackControl_FinalServerRetry()方法將會被呼叫。

接下來,IInteraction_DisplayMessage(ByVal strMessege As String)被呼叫,引數如假包換地被傳遞進來。這樣,就可以記錄日誌,或者做一些無害的處理。

第二種:ClientError

如果訊息根本不能被傳遞給伺服器端,比如伺服器關閉。

這時候,ECC的IPlaybackControl_FinalClientRetry()方法將會被呼叫。

接下來,IInteraction_DisplayMessage(ByVal strMessege As String)被呼叫。

 

Microsoft、Windows是 Microsoft Corporation 在美國和/或其他國家(地區)的註冊商標或商標。
本文提到的其他產品和公司名稱可能是其各自所有者的商標。

Edited by to:zhengyun@tomosoft.com">zhengyun (at) tomosoft.com


來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/10752019/viewspace-958160/,如需轉載,請註明出處,否則將追究法律責任。

相關文章