交談優先權

交談優先權是一組使用者定義的規則,其中每項規則都會指定一個優先權等級以及用以判斷哪些 Service Broker 交談要指派該優先權等級的準則。具有高優先權等級之交談的訊息通常會在具有低優先權等級之交談的訊息之前傳送或接收。

交談優先權的用途

交談優先權可用來進行下列動作:

  • 識別優先順序高於其他交談的交談。

  • 支援不同的服務層,其中支付較高費用之客戶的訊息會在支付較低費用之客戶的訊息之前傳送。

  • 客戶要求優先於背景工作。例如,新的客戶註冊應該比傳送商務交易摘要至資料倉儲具有更高的優先權。

交談優先權和交談端點

交談優先權是使用 CREATE BROKER PRIORITY 陳述式在每個資料庫中建立的。每個交談優先權都會定義下列項目:

  • 交談優先權的名稱。

  • 要指派 Service Broker 交談的優先權等級。這些等級會指定為 1 (最低) 至 10 (最高) 之間的整數。預設值為 5。

  • 決定哪些交談要套用此優先權等級的準則如下:

    • 合約名稱或 ANY。

    • 本機服務名稱或 ANY。

    • 遠端服務名稱或 ANY。

Service Broker 會在建立交談端點時,將優先權等級指派給端點。每個交談都具有兩個交談端點:

  • 起始端交談端點會讓交談的某一端與起始端服務和起始端佇列產生關聯。起始端交談端點是在執行 BEGIN DIALOG 陳述式時建立的。與起始端交談端點相關聯的作業包括下列項目:

    • 從起始端服務傳送。

    • 從起始端佇列接收。

    • 從起始端佇列取得下一個交談群組。

  • 目標交談端點會讓交談的另一端與目標服務和佇列產生關聯。目標交談端點是在起始端的第一則訊息放入目標佇列時建立的。與目標交談端點相關聯的作業包括下列項目:

    • 從目標佇列接收。

    • 從目標服務傳送。

    • 從目標佇列取得下一個交談群組。

哪一項服務會評估為本機或遠端服務端視交談端點的類型而定:

  • 若為起始端交談端點,起始端服務就是本機服務,而目標服務就是遠端服務。

  • 若為目標交談端點,目標服務就是本機服務,而起始端服務就是遠端服務。

Service Broker 如何指派優先權等級

Service Broker 會在建立交談端點時,指派交談優先權等級。交談端點會保留優先權等級,直到交談結束為止。新的優先權或現有優先權的變更不會套用至現有的交談。

Service Broker 會根據合約和服務準則與端點屬性最相符的交談優先權,將優先權等級指派給交談端點。下表將顯示相符優先順序:

端點合約

端點本機服務

端點遠端服務

優先權合約

優先權本機服務

優先權遠端服務

優先權合約

優先權本機服務

ANY

優先權合約

ANY

優先權遠端服務

優先權合約

ANY

ANY

ANY

優先權本機服務

優先權遠端服務

ANY

優先權本機服務

ANY

ANY

ANY

優先權遠端服務

ANY

ANY

ANY

Service Broker 會先尋找指定的合約、本機服務和遠端服務與交談端點所使用之項目相符的優先權。如果找不到相符項目,Service Broker 就會接著尋找合約和本機服務與端點所使用之項目相符的優先權,其中遠端服務指定為 ANY。然後,針對優先順序表格中所列的所有變化繼續進行。如果找不到相符項目,此端點就會被指派預設優先權 5。

Service Broker 通訊協定不會在交談端點之間傳輸優先權等級。Service Broker 會獨立地將優先權等級指派給每個端點。若要讓 Service Broker 指派優先權等級給起始端和目標交談端點,您必須確保這兩個端點都由交談優先權所涵蓋。如果起始端和目標交談端點位於個別的資料庫中,您就必須在每個資料庫中建立交談優先權。如果起始端和目標端點位於相同的資料庫中:

  • 您可以使用指定交談所使用之合約名稱的單一交談優先權以及同時代表本機和遠端服務名稱的 ANY,藉以涵蓋這兩個交談端點。

  • 您可以使用兩個交談優先權來分別涵蓋每個交談端點:

    • 起始端端點的單一交談,其中指定了 LOCAL_SERVICE_NAME 的起始端服務名稱和 REMOTE_SERVICE_NAME 的目標服務名稱。

    • 目標端點的單一交談,其中指定了 LOCAL_SERVICE_NAME 的目標服務名稱和 REMOTE_SERVICE_NAME 的起始端服務名稱。

通常系統會針對某個交談的兩個交談端點指定相同的優先權等級。雖然您可以針對每個端點的指定不同的優先權等級,但是這樣做並不表示以某個方向傳送訊息會比其他方向更快速。從某個交談端點傳送的訊息會在另一個端點接收。因此,每個訊息傳輸都會受到指派給這兩個端點的優先權等級所影響。例如,您可以設定交談,讓起始端交談端點具有優先權等級 10 而目標端點具有優先權等級 1。在此情況下:

  • 使用優先權等級 10 從起始端服務傳輸的訊息會使用優先權等級 1 從目標佇列接收。

  • 使用優先權等級 1 從目標服務傳輸的訊息會使用優先權等級 10 從起始端佇列接收。

當下列條件成立時,交談群組被指派的優先權等級會與指派給任何交談的最高優先權等級相同:

  • 交談是群組的成員。

  • 交談目前在服務佇列中具有訊息。

如果資料庫中尚未建立任何交談優先權,則資料庫中的所有交談端點都會被指派預設優先權 5。

交談優先權不會影響訊息轉送,因為這項作業永遠以預設優先權等級 5 運作。

交談優先權範例

請考慮含有下列項目的系統:

  • 包含 InitiatorServiceInitiatorQueueInitiatorDB

  • 包含 TargetServiceTargetQueueTargetDB

  • 名為 SimpleContract 的合約,其中指定 RequestMessages 是從 InitiatorService 傳送至 TargetService。它也指定 ReplyMessages 是從 TargetService 傳送至 InitiatorService

這個指令碼會針對起始端交談端點及其相關聯的作業指定優先權等級:

  • RequestMessage 的 SEND (從 InitiatorServiceTargetQueue)。

  • ReplyMessage 的 RECEIVE (從 InitiatorQueue)。

USE InitiatorDB;
GO
CREATE BROKER PRIORITY InitiatorToTargetPriority
    FOR CONVERSATION
    SET (CONTRACT_NAME = SimpleContract,
         LOCAL_SERVICE_NAME = InitiatorSerivce,
         REMOTE_SERVICE_NAME = N'TargetService',
         PRIORITY_LEVEL = 3);
GO

這個指令碼會針對目標交談端點及其相關聯的作業指定優先權等級:

  • RequestMessage 的 RECEIVE (從 TargetQueue)。

  • ReplyMessage 的 SEND (從 TargetServiceInitiatorQueue)。

USE TargetDB;
GO
CREATE BROKER PRIORITY TargetToInitiatorPriority
    FOR CONVERSATION
    SET (CONTRACT_NAME = SimpleContract,
         LOCAL_SERVICE_NAME = TargetService,
         REMOTE_SERVICE_NAME = N'InitiatorService',
         PRIORITY_LEVEL = 3);
GO

優先權如何運作

一般而言,Service Broker 會先傳送和接收高優先權交談的訊息,然後再傳送和接收低優先權交談的訊息。高優先權交談的訊息在佇列中花費的時間會比低優先權的訊息花費的時間更少。

接收優先權等級

優先權等級永遠會套用至從佇列接收訊息或交談群組識別碼的作業。

優先權等級是決定 RECEIVE 所擷取之訊息集合以及擷取訊息之順序的其中一項因素:

  • 每個 RECEIVE 陳述式永遠都會從一個交談群組擷取訊息:

    • 沒有 WHERE 子句的 RECEIVE 會擷取屬於在佇列中具有訊息之最高優先權解除鎖定交談群組的訊息。

    • 具有 WHERE 子句的 RECEIVE 會擷取 WHERE 子句中指定之交談群組的訊息。

  • 在交談群組內部,RECEIVE 會根據群組中交談的優先權等級來擷取訊息。具有最高優先權等級之交談的所有訊息會優先擷取,然後是次高優先權等級之交談的訊息,依此類推。

  • 在交談內部,系統會按照傳送訊息的相同順序來擷取這些訊息。

GET CONVERSATION GROUP 會從在佇列中具有訊息之解除鎖定群組的集合傳回具有最高優先權等級的群組。

傳輸優先權等級

某個執行個體之傳輸佇列中的訊息是依照下列順序傳輸的:

  • 其相關之交談端點的優先權等級。

  • 在優先權等級內部,交談中的傳送順序。

Service Broker 會協調某個 Database Engine 執行個體中所有傳輸佇列之間的優先權等級。Service Broker 會先傳輸所有傳輸佇列中優先權 10 交談的訊息,然後是優先權 9 交談的訊息,依此類推。

訊息效能的相對差異會隨著優先權等級的差異而增加。在使用兩個相鄰優先權等級 (例如 9 和 10) 的系統中,較高優先權等級的訊息具有小幅效能優勢。在使用兩個分隔很遠之優先權等級 (例如 1 和 10) 的系統中,較高優先權等級的訊息具有較大的效能優勢。在使用多重優先權等級的系統中,大部分處理作業都會配置為第 2 或第 3 高優先權等級。

如果 HONOR_BROKER_PRIORITY 資料庫選項設定為 ON,在交談優先權中指定的優先權等級只會套用至傳輸佇列中的訊息。如果 HONOR_BROKER_PRIORITY 設定為 OFF,則放置於該資料庫之傳輸佇列中的所有訊息都會使用預設優先權等級 5 進行傳送。使用 sys.transmission_queue 檢視時,這些訊息仍然會顯示從端點收到的優先權等級,但是系統會使用預設優先權等級來傳輸訊息。

由於優先權等級會套用至傳輸佇列中的訊息,因此它們通常不會影響在相同 Database Engine 執行個體之服務之間傳送的訊息。傳送至相同執行個體之服務的訊息會直接放入服務的佇列中,而不會通過傳輸佇列。不過,某些條件可能會導致本機訊息放入傳輸佇列中,例如某些錯誤類型或非使用中的目的地佇列。如果訊息儲存在傳輸佇列中,系統就會套用相關的優先權等級。

訊息和訊息片段可能會不依照優先權順序傳送:

  • Service Broker 會使用訊息片段的區塊,在 Database Engine 的執行個體之間傳送訊息。如果許多具有不同優先權的訊息片段準備要傳送至某個執行個體,Service Broker 可能會在單一區塊中傳送所有片段。位於區塊結尾之某些片段的優先權等級可能會比等候傳輸至另一個執行個體的訊息片段更低。

  • Service Broker 含有一項防止資源匱乏機制,可協助避免大量高優先權訊息封鎖低優先權訊息。已經等候一段長時間的低優先權訊息仍然可以進行傳送,即使佇列中存在較高優先權的訊息也一樣。

雖然個別訊息或訊息片段可能會不依照優先權順序傳送,但是考量到傳送許多訊息的情況下,其影響應該很小。