Share via


了解啟動何時發生

Service Broker 啟動程序是由兩個步驟所組成。第一個步驟,Service Broker 判斷啟動是否為必要。第二個步驟,Service Broker 判斷啟動是否已發生。雖然內部啟動與外部啟動的正確程序各有不同,不過任何一個策略所牽涉的整體概念都是相同的。

判斷啟動是否為必要

每當新佇列讀取器含有有用的工作要執行,就會需要啟動。佇列監視器會決定是否需要啟動。Service Broker 會為每個含有啟動 STATUS = ON 的佇列,或是每個已經註冊 QUEUE_ACTIVATION 事件通知的佇列,建立佇列監視器。動態管理檢視 sys.dm_broker_queue_monitors (Transact-SQL) 會列出執行個體內使用中的佇列監視器。每個佇列監視器會追蹤下列項目:

佇列是否包含準備接收的訊息

佇列上的 RECEIVE 陳述式多久一次傳回空的結果集

目前為佇列執行的啟動預存程序有多少個。

佇列監視器會每隔幾秒鐘檢查是否需要啟動,以及何時會發生一個或多個下列事件:

  • 佇列上到達的新訊息。

  • SQL Server 會為佇列執行 RECEIVE 陳述式。

  • 包含 RECEIVE 陳述式的交易會回復。

  • 佇列監視器啟動的所有預存程序會結束。

  • SQL Server 會為佇列執行 ALTER 陳述式。

如果下列其中一項為 True,則需要啟動:

  • 新訊息所到達的佇列,不包含未閱讀的的訊息,而且沒有為佇列執行的啟動預存程序。

  • 佇列包含未閱讀的訊息,在 GET CONVERSATION GROUP 陳述式或是沒有 WHERE 子句的 RECEIVE 陳述式中沒有等待的工作階段,而且 GET CONVERSATION GROUP 陳述式或是沒有 WHERE 子句的 RECEIVE 陳述式未在幾秒鐘之內傳回空的結果集。換句話說,訊息會在佇列上持續累積,因為啟動的程序無法夠快速地讀取它們。

事實上,此程序允許佇列監視器告知處理佇列的佇列讀取器數目,是否能趕得上內送訊息傳輸。請注意這個方法將交談群組鎖定納入考量。因為一次只能有一個佇列讀取器可以處理交談的訊息,所以啟動佇列讀取器以回應較簡單的方法 (例如佇列中未閱讀訊息的數目) 可能會浪費資源。因此,Service Broker 啟動會考慮新的佇列讀取器是否將有有用的工作要執行。

例如,查詢可能在單一交談上包含大量未處理的訊息。在此情況下,只能有一個佇列讀取器可以處理訊息:佇列監視器會啟動另一個佇列讀取器。第二個佇列讀取器會在 RECEIVE 陳述式中等待,因為所有的訊息都屬於單一交談。只要佇列中的所有訊息都屬於相同的交談,而且第二個佇列讀取器仍然在執行中,佇列監視器就不會啟動另一個佇列讀取器。

判斷啟動是否發生

一旦 Service Broker 判斷啟動為必要的,Service Broker 必須決定啟動是否會發生。

對於內部啟動,佇列監視器會在執行中的程式數目小於為佇列設定的 MAX_QUEUE_READERS 值時,啟動該啟動預存程序的新執行個體。如果執行中程式的數目等於或大於 MAX_QUEUE_READERS 值,佇列監視器不會啟動預存程序的新執行個體。管理檢視 sys.dm_broker_activated_tasks (Transact-SQL) 包含 Service Broker 啟動的預存程序之資訊。

對於外部應用程式,Service Broker 沒有關於可能與佇列搭配使用的不同佇列讀取器之數目的資訊。此外,在引發啟動事件的時間與讀取器開始讀取佇列的時間之間,可能需要一些啟動時間。因此,Service Broker 會為要回應的外部應用程式提供逾時。逾時期間,Service Broker 並不會產生其他通知。一旦應用程式呼叫在佇列上的 RECEIVE 或是逾時過期時,如果需要啟動,Service Broker 會建立其他的事件通知。外部應用程式會監視事件通知,另一方面該程式會持續執行以判斷讀取事件是否需要更多的佇列讀取器。