SQL Server 2005 Service Broker 初探
一、引言
SQL Server 2005 的一個主要成就是可以實現可靠、可擴充套件且功能完善的資料庫應用程式。與 .NET Framework 2.0 公共語言執行庫 (CLR) 的整合使開發人員可以將重要的業務邏輯與儲存過程合併,而 T-SQL 和 XML 中的新增功能擴充套件了資料操作的可用範圍以及開發人員可用的儲存功能。另一個重要功能是 SQL Server Service Broker,它為資料庫應用程式增加了可靠、可擴充套件、分散式非同步功能。
二、為什麼要編寫非同步排隊操作?在開發 SQL Server 2005 時,我們與成功開發過大型可擴充套件資料庫應用程式的人員進行了交談。結果發現他們幾乎所有的應用程式中都有一個或多個操作是以非同步排隊方式執行的。股票交易系統中的結算活動是排隊的,這樣可以在後臺進行結算,在前端處理其他交易。訂單輸入系統中的發貨資訊放在一個排隊中,稍後將由另一臺伺服器(通常位於其他位置)上執行的發貨系統讀取。旅行預訂系統在客戶填寫完路線後再進行實際的預訂,並在預訂完成後傳送確認電子郵件。在所有這些示例中,許多工作都是通過非同步方式完成的,從而提高了系統的響應速度,因此使用者無須等待工作完成就可以收到響應。
在大多數大型系統中,經過仔細分析後都可以發現,許多處理都可以通過非同步方式完成。雖然應用程式中的排隊任務無須立即完成,但系統必須確保這些任務能夠可靠地完成。Service Broker 使非同步排隊任務的執行可靠並且易於實現。
使應用程式中的部分任務非同步執行的另一個優勢是這些任務的處理工作可以在資源可用時完成。如果訂單輸入系統中的發貨任務可以從佇列中執行,發貨系統就無需具有處理峰值訂單負載的能力。在許多訂單輸入系統中,峰值訂單率可能是平均訂單率的兩倍或三倍。由於訂單輸入系統必須具有處理峰值負載的能力,因此大量處理能力在很大一部分時間內都處於閒置狀態。如果在出現峰值時對非同步任務進行排隊並在空閒時執行,將顯著提高系統的利用率。
既然非同步排隊應用程式具有許多優勢,為什麼不以這種方式編寫所有應用程式?這是因為編寫非同步排隊應用程式相當困難!許多嘗試在應用程式中使用資料庫表作為佇列的開發人員發現,實際操作遠比想象的困難。作為佇列的表中包含多個程式,包括同時插入、讀取和刪除幾條記錄。這將帶來併發問題、降低系統效能並導致頻繁當機。儘管許多開發人員都成功地解決了這些難題,但實際操作卻非常困難。Service Broker 通過使佇列成為 SQL Server 2005 資料庫中的第一級資料庫物件解決了這些問題。編寫佇列的大多數難題都已解決,因此開發人員可以專注於編寫非同步應用程式,而不是編寫排隊基礎結構。本文的其餘內容將討論編寫排隊應用程式涉及到的難題,並解釋 Service Broker 如何幫助您解決這些難題。
訊息的完整性
在許多非同步排隊應用程式中,排隊的訊息實際上是有價值的業務物件。例如在訂單輸入系統中,如果將發貨資訊放入佇列中以便稍後處理,那麼丟失排隊的資料將意味著無法按訂單發貨。許多可靠的訊息傳送系統都將訊息儲存在檔案系統中,因此磁碟驅動器的損壞將導致訊息丟失。Service Broker 將訊息儲存在隱藏的資料庫表中,因此 SQL Server 為保護資料而提供的所有資料完整性功能同樣可用於保護排隊的訊息。如果使用資料庫映象進行故障恢復,當因資料庫故障而轉移到第二個資料庫後,所有訊息都會轉移到第二個資料庫中,這樣 Service Broker 應用程式將繼續執行而不會丟失任何資料。
多讀取器佇列
多讀取器佇列是一種擴充套件非同步應用程式的最有效的方式。為證明這一點,我將通過大家都熟悉的兩個示例說明如何進行排隊。
在雜貨店排隊
大多數雜貨店都可以增設多個佇列。每個收銀臺都有其自己的佇列,因此要購買某些商品,您需要選擇一個佇列。如果您像我一樣,大多數時候選擇的佇列中都有一個滿載而歸的顧客排在您前面,他/她購買的很多商品都需要核實價格,而且要使用第三方遠期支票進行付款。在輪到您結帳之前,可能在您開始排隊時還沒有出門的顧客都已經為他們購買的商品付完了款。這個例子說明了使用多個佇列時的一個問題:即,如果排在前面的任務需要很長時間才能處理完,後面的任務將無法得到及時處理。
使用多個佇列的另一個主要問題是,新增一個佇列後需要在各佇列之間重新分配任務,在佇列之前來回移動任務可能會浪費很多時間。還以上面的雜貨店為例,當一個新的收銀臺開始工作時,想象一下許多顧客推著購物車蜂擁而至的場面吧。
在機場排隊
雖然航空公司並非高效率的典範,但大多數售票點的工作效率都比雜貨店要高,這是因為多個票務代理都在為一個佇列服務。由於只有一個佇列,因此您不必擔心排錯了隊。如果某個乘客佔用了較長的時間,其他票務代理仍可以繼續為其他乘客服務(假定有多個票務代理)。
具有多個讀取器的一個佇列也可以輕鬆擴充套件。如果佇列太長,可以增加代理而不必打斷佇列。某些代理也可以在接待完當前乘客後離開,而不會在佇列中造成混亂。
儘管可能會偏離主題,但我們仍以機場佇列為例來說明基於佇列的應用程式的另一個常見問題。假定排在一個佇列中的幾個人屬於一個團隊,比如說,我和我的家人正在登記準備去旅行。再假定我的家人由於到達時間不同而分散排在一個佇列中。如果我們希望坐在一起,那麼代理將需要預留一排坐位。如果我和妻子同時來到不同的票務代理處,則我可能預訂了第 4 排的 5 個座位,而我的妻子預訂了第 47 排的 5 個座位。這是多讀取器佇列的一個主要問題:即,如果在不同的執行緒中同時處理相關的訊息,將很難進行協調。請想象一下同時處理訂單標題和訂單內容的情景。處理訂單內容的讀取器會認為沒有相關的訂單標題,因為訂單標題還未讀入資料庫。為了正確工作,訂單內容必須多次重新查詢訂單標題,以確保訂單標題只是被延遲而不是不存在。
一種更簡單的方法是讓第一個到達售票處的乘客將所有相關乘客都叫到前面來,以便由一個售票處為所有這些乘客提供服務。 Service Broker 的功能與此類似,它在接收到一條訊息後鎖定相關的其他訊息。持有鎖定的讀取器可以接收佇列中屬於同一組的所有其他訊息,而其他讀取器都不能讀取這些訊息。在提交事務之前,訊息將一直保持鎖定狀態。該鎖定稱為“會話組”鎖定。會話組是開發人員定義的相關訊息組。例如,處理特定訂單所需的所有對話(訂單標題、訂單內容、庫存、發貨、帳單等等)可能被放入同一個會話組中。從其中一個會話讀取訊息時,將鎖定會話組中的其他訊息,這樣只有持有鎖定的讀取器可以處理佇列中的所有相關訊息。請注意,只鎖定一個組中的訊息,這一點非常重要。儘管可以同時處理上百個組,但任一時刻一個執行緒只處理一個組。在提交或回滾執行緒建立的事務之前,組將一直處於鎖定狀態。
我想通過這個例子說明的最後一個問題是,當持有會話組的事務被提交後,該會話組中的另一條訊息到達時會發生什麼情況。還以售票處為例,當我的家人都登記後,我的一個孩子才到達機場。由於原始事務已經結束,最後一位乘客可以由任一票務代理服務。只有在原始代理留下便條,說明該組中其他人員的位置時,新代理才能知道如何為最後一位乘客安排座位。同樣,當處理相關訊息組的事務完成時,必須記錄會話的“狀態”以便當該組中下一條訊息到達時,接收該訊息的佇列讀取器瞭解上一個事務停止時的位置。因為這是資料庫應用程式,所以儲存該狀態的位置應該是一張資料庫表。Service Broker 提供了一個會話組 ID,可以使用它來方便地將會話狀態和會話中的訊息相關聯。這是與會話組中每條訊息一起顯示的唯一識別符號。如果唯一識別符號用作儲存狀態的表中的金鑰,則訊息處理邏輯可以很容易地找到與接收到的每條訊息相關聯的狀態。另外,因為每次只有一個佇列讀取器可以處理來自特定會話組的訊息,所以開發人員不必擔心同時有兩個事務更新狀態行從而導致丟失狀態資訊。
以上示例說明,多讀取器佇列是擴充套件大型應用程式的一種簡單而有效的方法。Service Broker 提供的會話組鎖定機制使編寫使用多讀取器佇列的應用程式像編寫使用單讀取器佇列的應用程式一樣容易。
分佈
前面討論的佇列都假定位於一個資料庫中。為了開發適用於多種業務情況的鬆散耦合的分散式資料庫應用程式,我們需要進行擴充套件,以包括分散在網路中(通過可靠的訊息傳送進行通訊)的多個資料庫中的佇列。我們需要可靠的訊息傳送,因為如果使用資料庫確保佇列中訊息的完整性,但訊息卻在傳送到其他資料庫的過程中丟失,所有工作都將是徒勞的。
Service Broker 使用稱為“對話協議”的可靠訊息傳送協議來確保傳送到遠端佇列的訊息按順序到達並且僅到達一次。正如對話是雙向會話一樣,對話協議同時支援雙向的訊息傳送。
對話訊息具有標題,可確保訊息按正確順序安全地傳送到正確的目標位置。它包含序列號、訊息所在對話的識別符號、要傳送到的服務的名稱、安全性資訊以及用於控制訊息傳送的一些其他資訊。當目標位置成功接收到訊息後,它將發出確認,以便源位置知道已成功傳送了訊息。如果可能,確認資訊將包含在另一條訊息的標題中傳送回源位置,以儘可能減小訊息的數量。如果源位置在某一時限內沒有收到確認,將重新傳送該訊息直到成功傳送。
訊息傳送系統在傳送較大的訊息時經常會遇到問題。傳送以 GB 為單位的訊息會花幾分鐘時間,從而會佔用一段時間的網路連線。如果發生網路錯誤導致重新傳送訊息多次,將會嚴重影響網路效能。為了解決此問題,Service Broker 對話協議將大型訊息拆分成多個較小的片段,然後再單獨傳送每個片段。如果發生網路錯誤導致重新傳送,則只重新傳送傳送失敗的訊息片斷。因此,Service Broker 最大可以支援 2GB 的訊息,而許多可靠的訊息傳送系統只能傳送 100MB 或更小的訊息。
事務性訊息傳送
“僅一次”訊息處理需要使用事務性訊息。為了說明此問題,假定某個應用程式在處理訊息的過程中發生了錯誤。當應用程式重新啟動時,它如何才能知道是否要處理髮生錯誤時正在處理的訊息呢?資料庫中可能已經更新了訊息處理的結果,因此重新處理訊息可能產生重複的資料。唯一安全的處理方式是使接收訊息成為更新資料庫的同一事務的一部分。在系統崩潰時資料庫更新和訊息接收都回滾,因此資料庫和訊息佇列的狀態與系統崩潰前的狀態相同。
因為所有 Service Broker 操作都在資料庫事務環境中發生,所以保證了訊息傳送操作的 事務完整性。典型的 Service Broker 訊息處理事務包括以下步驟:
1. |
開始事務。 |
2. |
從會話組中接收一條或多條訊息。 |
3. |
從狀態表中檢索會話的狀態。 |
4. |
處理訊息並根據訊息內容對應用程式資料進行一項或多項更新。 |
5. |
傳送一些 Service Broker 訊息:即,將響應傳送到傳入的訊息或將訊息傳送到處理傳入訊息所需的其他服務。 |
6. |
如果此會話組包含其他訊息,則讀取和處理此會話組中的其他訊息。 |
7. |
使用新的會話狀態更新會話狀態表。 |
8. |
提交事務 |
Service Broker 事務性訊息傳送的一項重要功能是在任何時間如果崩潰或應用程式發生錯誤,事務將回滾並且一切都返回到事務開始時的狀態,即狀態不變、應用程式資料不變、訊息未傳送並且接收的訊息返回到佇列中。這使此類應用程式中的錯誤處理非常簡單。
佇列讀取器管理
在 Service Broker 應用程式的訊息處理過程中,佇列讀取器首先從佇列接收訊息。由於訊息始終從佇列中拉出,因此在訊息到達佇列時接收應用程式必須正在執行。許多非同步訊息應用程式都面臨著一個問題,即如何確保佇列讀取器在需要時處於執行狀態?有兩種傳統的方法:讓佇列讀取器成為連續執行的服務,或者使用觸發器,在每條訊息到達時,都將觸發訊息傳送系統。Windows NT 服務方法是指即使在不處理訊息時也執行應用程式。由於佇列讀取器頻繁開始和停止,觸發器方法可能會遇到效能問題。
Service Broker 採用稱為啟用的中間狀態方法來管理佇列讀取器。為設定啟用,DBA 將儲存過程與 Service Broker 佇列相關聯。當第一條訊息到達佇列時,啟用邏輯將啟動指定的儲存過程。儲存過程負責接收和處理訊息,直到佇列為空。佇列為空後,儲存過程可以終止以節省資源。
如果 Service Broker 確定訊息新增到佇列的速度比儲存過程能夠處理的速度快,啟用邏輯將開始其他的儲存過程,直到儲存過程能夠處理傳入的訊息或者達到了為佇列配置的儲存過程的最大數量。由於為佇列提供服務的佇列讀取器數量隨著傳入訊息速率的更改增大或減小,因此所有時間都將執行適當數量的佇列讀取器。
關於 Service Broker 的一個常見問題是“為什麼要將訊息傳送功能內建在資料庫中?資料庫外部難道沒有足夠可靠的訊息傳送系統?”
我希望前面的資訊已經說明了為什麼要在資料庫引擎中內建 Service Broker,下面提供了要在資料庫中傳送訊息的一些其他理由:
• |
訊息和資料的單客戶端連線。除了上一部分中提到的統一程式設計模型,還具有一些其他顯著的優勢:
| ||||||
• |
資料和訊息之間整合的管理、部署和操作。用於保護和管理資料庫資料的所有工具和技術同樣適用於訊息:
| ||||||
• |
將訊息傳送功能內建在資料庫中還有一些顯著的效能優勢。
|
Service Broker 功能通過 SQL Server 中的新物件啟用,這些新物件可以由一組 T-SQL 擴充套件來建立和操作。為了資料庫程式設計師的方便,使用了他們熟悉的用於配置其他資料庫物件的 CREATE、ALTER 和 DROP DDL 語句來配置 Service Broker 應用程式。用於建立 Service Broker 對話以及在對話中傳送和接收訊息的命令是 Transact SQL 語言的 DML 擴充套件。接收命令的語法與選擇命令相似,它返回包含訊息的行集,就像選擇命令返回包含行的行集一樣。熟悉 Transact SQL 程式設計的開發人員會發現學習 Service Broker 程式設計非常容易。用於為 Service Broker 程式設計的客戶端 API 與用於為所有資料庫程式設計的 API 相同,例如 OLEDB、ODBC、ADO、ADO.NET 等等。下面是 Service Broker 使用的物件。
佇列
Service Broker 使用佇列在訊息傳送程式和訊息接收程式之間提供鬆散耦合。傳送程式可以使用 SEND 命令將訊息放到佇列中,然後應用程式繼續操作並依靠 Service Broker 來確保訊息到達其目標位置。
佇列允許較大的計劃靈活性。例如,傳送程式可以傳送多條訊息以供多個接收程式並行處理。接收程式可能在訊息傳送很長時間後才處理訊息,但由於傳入訊息進行了排隊,因此接收程式可以按其自己的速率處理訊息,而且傳送程式無須等待接收程式完成處理便可繼續操作。
對話
Service Broker 還實現了對話,對話是兩個端點之間的雙向訊息流。對話中的所有訊息都進行了排序,而且對話訊息總是按照傳送的順序傳送。該順序在事務、輸入執行緒、輸出執行緒以及系統崩潰和重新啟動過程中都保持不變。有些訊息系統可以確保單個事務中傳送或接收的訊息順序,但不能確保多個事務中的順序,因此 Service Broker 對話具有獨特的優勢。
對話是一種會話型別。Service Broker 會話是持久可靠的通訊通道。在以後的 SQL Server 版本中,Service Broker 將包括一對多的單向會話,也稱為可靠的“釋出-訂閱”。在 SQL Server 2005 中,對話是唯一的會話型別,因此這兩個術語同義。
每條訊息都包括唯一標識與它相關的對話的會話控制程式碼。例如,某個訂單輸入應用程式可能同時使用發貨應用程式、庫存應用程式和帳單應用程式開啟了對話。因為每個應用程式中的訊息都具有唯一的會話控制程式碼,所以可以輕鬆地確定傳送每條訊息的應用程式。
訊息型別
當前,所有 Service Broker 訊息都與特定的訊息型別相關聯。訊息型別是與訊息一起傳送的標籤,因此接收訊息的應用程式可以確定所接收訊息的型別。此外,如果訊息包含 XML 文件,則訊息型別可以與 XML 架構集合相關聯。如果為某個訊息型別指定了架構集合,則所接收的該型別訊息將在收到時根據架構集合進行驗證,而沒有通過架構驗證的訊息將會被拒絕。
規範
Service Broker 規範是一個訊息型別集合。一個對話總是與一個規範相關聯,而規範定義哪些訊息型別可以通過對話傳送。
服務
Service Broker 服務將一個或多個規範與一個佇列相關聯。規範定義可以將哪些訊息型別傳送到佇列。服務名稱用於建立對話的端點。服務名稱用作實際佇列的別名,因此您可以編寫引用服務名稱的 Service Broker 程式,然後在部署應用程式時將它與實際佇列相關聯。
大多數程式語言書籍都以“Hello World”示例開始,因此我們也在 Service Broker 中使用 Hello World 作為示例。為簡化示例,我使用可以從 SQL Server Management Studio 查詢視窗執行的 T-SQL 進行編寫。大多數 Service Broker 應用程式將作為普通的資料庫應用程式,這些應用程式由通過 ADO 或 ADO.NET 與資料庫進行通訊的可執行程式和使用 T-SQL 或 .NET 語言編寫的 SQL Server 儲存過程構成。
要傳送和接收訊息,必須首先建立向 Service Broker 描述應用程式的訊息傳送部分的後設資料物件。在 SQL Server 2005 中,使用新新增的 DDL 語句來建立、修改和刪除 Service Broker 後設資料。
-- 建立要使用的資料庫 Create Database HelloWorldDB go Use HelloWorldDB go -- 建立要使用的兩種訊息型別。我們要使用的訊息將是 -- 字串而不是 XML - 因此無需進行驗證 CREATE MESSAGE TYPE [HelloWorldRequest] VALIDATION = NONE CREATE MESSAGE TYPE [HelloWorldResponse] VALIDATION = NONE -- 建立一個限制此對話方塊中訊息型別 -- 的規範。請求由對話方塊的初始化程式發出 -- 響應訊息由對話方塊目標傳送。 CREATE CONTRACT [HelloWorldContract] ( [HelloWorldRequest] SENT BY initiator, [HelloWorldResponse] SENT BY target ) -- 建立對話方塊在其間通訊的兩個佇列。A -- 對話方塊請求兩個佇列。 CREATE QUEUE [HelloWorldTargetQueue] CREATE QUEUE [HelloWorldInitiatorQueue] -- 建立命名對話方塊端點的服務。服務會將 -- 會話端點連線到佇列。 CREATE SERVICE [HelloWorldRequestService] ON QUEUE [HelloWorldTargetQueue] ( [HelloWorldContract] ) CREATE SERVICE [HelloWorldResponseService] ON QUEUE [HelloWorldInitiatorQueue] go
現在已經設定了後設資料,可以傳送訊息了。請注意,由於初始化程式和目標服務位於同一 SQL Server 例項中,因此訊息將直接轉到目標佇列而不會通過傳送佇列傳送。由於 Service Broker 內建在資料庫中,因此可以進行此項效能優化。
Use HelloWorldDB go SET NOCOUNT ON DECLARE @conversationHandle uniqueidentifier Begin Transaction -- 開始 Hello World 服務的對話 BEGIN DIALOG @conversationHandle FROM SERVICE [HelloWorldResponseService] TO SERVICE 'HelloWorldRequestService' ON CONTRACT [HelloWorldContract] WITH ENCRYPTION = OFF, LIFETIME = 600; -- 傳送訊息 SEND ON CONVERSATION @conversationHandle MESSAGE TYPE [HelloWorldRequest] (N'Hello World') commit
讓我們檢視目標佇列以確保成功傳送了訊息。
Use HelloWorldDB go -- 檢查目標佇列以確認訊息已送達 select * from [HelloWorldTargetQueue] go -- 將訊息主體轉換為字串,以便我們檢視其中包含的內容 select cast(message_body as nvarchar(MAX)) from [HelloWorldTargetQueue] go
現在可以從目標佇列中接收訊息並將響應傳送回初始化程式。
-- 使用 Receive 命令可從佇列接收訊息 -- 宣告變數以儲存接收到的資料 SET NOCOUNT ON DECLARE @conversationHandle uniqueidentifier declare @message_body nvarchar(MAX) declare @message_type_name sysname; -- Service Broker 命令總是位於事務中 Begin Transaction; -- Receive 命令的格式類似於一個選擇列表。首先列出 -- 要獲取的列,然後指定要從中獲取訊息 -- 的佇列 RECEIVE top(1) -- 只接收一條訊息,因此我們可以直接儲存到變數中。 @message_type_name=message_type_name, -- 接收的訊息型別 @conversationHandle=conversation_handle, -- 對話的識別符號 -- 我們通過下列語句接收該訊息 @message_body=message_body -- 作為 -- varbinary(MAX) blob 的訊息內容 FROM [HelloWorldTargetQueue] print @message_body -- 如果這是一條 hello world 訊息,則用相應的問候語回答 if @message_type_name = N'HelloWorldRequest' Begin SEND ON CONVERSATION @conversationHandle -- 使用下列訊息接收語句的相同會話 MESSAGE TYPE [HelloWorldResponse] (N'Hello From '+@@servername ) -- 這是我們希望從初始化程式接收的唯一訊息,因此 -- 現在可以安全地結束對話。 END CONVERSATION @conversationHandle End -- 提交事務 -- 如果此時我們回滾,所有內容將退回到 -- 我們開始時的狀態 – 訊息會返回到佇列,並且沒有傳送響應 Commit go -- 確認我們從佇列中刪除了訊息 select cast(message_body as nvarchar(MAX)) from [HelloWorldTargetQueue] go
響應已在對話中傳送回初始化程式佇列,現在檢查響應是否成功到達:
Use HelloWorldDB go select cast(message_body as nvarchar(MAX)) from [HelloWorldInitiatorQueue] go
... 最後接收並顯示響應訊息:
RECEIVE cast(message_body as nvarchar(MAX)) FROM [HelloWorldInitiatorQueue]
現在已經成功地向 Service Broker 傳送了訊息並收到了響應。如果希望檢視剛剛執行的命令的詳細說明,請參見 SQL Server 聯機書籍所提供的豐富訊息。如果希望擴充套件此示例以在兩個資料庫之間使用,您需要新增從發起程式伺服器到目標伺服器的路由和從目標返回到初始化程式的路由。Service Broker 路由將 BEGIN DIALOG CONVERSATION 命令中指定的服務名稱對映到傳送訊息所需的實際網路地址資訊。有關路由和安全性的詳細資訊,請參見 SQL Server 聯機書籍。
現在您已經看到了 Service Broker 是如何工作的,下面將介紹可以使用 Service Broker 開發的部分應用程式。
訂單輸入
許多程式都使用訂單輸入作為示例,因為大多數人都瞭解該過程。即使沒有開發過訂單輸入系統的開發人員至少都使用過訂單輸入系統進行訂貨。
基於 Service Broker 的訂單輸入系統使用佇列來將系統的子系統連線到一起。這不僅增加了並行度並且提高了效率,而且使配置和體系結構具有非常大的靈活性。
在本示例中,Service Broker 用於連線四個鬆散耦合的服務以處理每個訂單。在訂單輸入服務將訂單標題和訂單內容插入到資料庫中時,它根據計費、發貨、庫存和信貸限額服務對訊息進行排隊以完成對訂單的處理。Service Broker 允許四項服務並行執行,從而縮短了系統的響應時間。
根據系統的業務需求,訂單輸入服務可以等待收到所有四項服務的響應後返回到使用者,也可以在提交初始事務後立即返回而在後臺執行其餘的服務。實現每個操作都會對訂單輸入服務進行一些更改。每種情況中的其他服務保持不變。
使用 Service Broker 連結服務還提供了幾個部署選項。所有五項服務可以在同一臺伺服器上執行,也可以根據需要分散在五臺伺服器(在服務的負載平衡時可以為更多的伺服器)上執行以提供所需的效率。服務可以部署為儲存過程或外部應用程式。這種靈活性對 ISV 非常有用,ISV 可以根據客戶對效能、冗餘和效率的需求建立單個程式碼庫並在各種配置中進行部署。
並行儲存過程
最初發明觸發器時,資料庫公司通常對庫存表使用觸發器,在庫存量太低時自動發出訂單。雖然這是一個很好的概念,但是隻有很少的系統使用了觸發器,因為在觸發器中執行大段程式碼的額外開銷會使資料庫的更新速度非常慢。Service Broker 允許觸發器對要完成的工作進行排隊,以便觸發器可以完成和允許提交初始事務,從而使這類應用程式可以被廣泛採用。然後,排隊的工作在單獨的事務中完成,甚至可以在不同的資料庫中完成。SQL Server 2005 對“查詢通知”和“事件通知”使用此模型。
Service Broker 還允許儲存過程並行開始幾個其他的儲存過程。此功能可以顯著縮短響應時間。例如,某個呼叫中心應用程式對傳入的呼叫使用呼叫方 ID 查尋有關正在呼叫的客戶的所有資訊,因此客戶服務代表可以獲取所有相關資訊。在許多情況下,必須從不同系統上的不同資料庫中獲取這些資訊。可以使用遠端查詢獲取所有這些資訊,但響應時間可能太長。Service Broker 可以同步將請求排隊到所有遠端服務並在其輸入佇列上等待結果。因為並行處理所有請求,所以總響應時間將縮短。
批處理批處理系統中經常會使用 Service Broker 應用程式。大多數批處理由許多小型的半獨立處理構成,必須對這些半獨立處理進行計劃和協調。獨立執行子過程允許每個子系統按其最佳速度執行,因此可以提高效率。
在本示例中,將會不間斷地在輸入佇列上累計對批計劃過程的輸入,包括預購、預測、返回等等。當計劃引擎執行時,它閱讀佇列中的輸入、進行分析、然後將請求排隊到處理計劃輸出的子過程。輸出佇列允許在一臺伺服器或多臺伺服器上並行地單獨執行子過程。這允許根據需要擴充套件任意多臺伺服器以滿足處理負載的需求。
旅行預訂
以前,我經常為碩士研究生講授分散式資料庫類。我曾經使用的一個分散式事務的示例是旅行社在同一事務中預訂了飛機票、旅館房間和租車服務,因為客戶在無法進行航空旅行時不會預訂旅館。像許多示例一樣,直到有一天一位來自真正旅行社的程式設計師來到了教室裡,我們才瞭解真實的情況。他告訴我真正的旅行社不是這樣工作的。在預訂旅館房間時,航空公司不允許任何人鎖定其預訂表格和座位安排。預訂根據當前的可用性完成,並且如果在實施預訂時已經沒有空餘的座位或房間,將給客戶打電話以確保新的預訂滿足客戶需求。
在旅行預訂 Web 站點示例中,預訂根據有關航空公司和旅店可用性的資料表來完成。這些表包含來自航空公司或旅館的資訊。資訊會經常更新,但總是會有一點過時。實際的預訂在客戶預約旅行後才發生,並可能在客戶取消旅行後被取消。
這種延遲的活動非常適合 Service Broker 體系結構。記錄客戶旅行安排的事務將訊息提交到進行實際預訂的後端服務。預訂服務讀取佇列中的訊息並在單獨的事務中處理每個預訂。預訂服務通過各種協議與預訂航空公司和旅館服務的系統進行通訊。這些通訊可能包括 Web 服務、SNA、HTTP、EDI、傳真、Service Broker 等等。由於對到預訂服務的輸入進行了排隊,因此這些協議的不同滯後時間不會帶來問題。如果佇列太長,Service Broker 啟用可以啟動更多的佇列讀取器來處理負載。如果負載達到預訂伺服器能夠處理的最大值,則可以通過向路由表新增行來新增更多的伺服器。
在成功完成特定路線的所有預訂後,會將一條訊息排隊到 SQLiMail 伺服器以向客戶傳送確認電子郵件。如果一項或多項預訂未能完成,將通知客戶服務代表來幫助重新預訂旅行。
“處理更新”服務在後臺執行,並定期從旅館和航空公司接收可用性資訊。這些資訊被轉換為常見的 XML 格式,然後通過通知服務釋出到 Web 叢集中的伺服器以更新旅館和航空公司的可用性表。
鬆散耦合的 Service Broker 體系結構允許通過載入軟體、配置資料庫和訂閱可用性反饋來將 Web 伺服器新增到伺服器叢集。可以編寫指令碼以使進行操作時只需最少的手動干預。為向預訂服務新增更多後端伺服器,必須安裝和配置該服務,然後必須將新的伺服器地址新增到 Web 伺服器中的路由表。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/16436858/viewspace-629792/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- SQL Server 2005中Service Broker應用的組成SQLServer
- 配置SQL Server Service Broker來傳送儲存過程資料(下)SASQLServer儲存過程
- 配置SQL Server Service Broker來傳送儲存過程資料(上)CYSQLServer儲存過程
- SQL Server Service Broker建立單個資料庫會話(訊息佇列)SQLServer資料庫會話佇列
- 關於SQL Server 2008是否是SQL Server 2005的一個Service PackSQLServer
- 初探SQL Server MDXSQLServer
- SQL server 2005 expressSQLServerExpress
- Sql Server 2005函式SQLServer函式
- SQL SERVER 2005 配置-saSQLServer
- SQL SERVER2005建Link ServerSQLServer
- 初探SQL Server CE + Codesmith用法SQLServerMIT
- Sql Server 2005新增T-sql特性SQLServer
- XML Support in Microsoft SQL Server 2005XMLROSSQLServer
- PowerShell連線 SQL Server 2005SQLServer
- Monitoring Tempdb in SQL Server 2005SQLServer
- 微軟SQL Server 2005速成版微軟SQLServer
- SQL Server2005快捷鍵SQLServer
- SQL SERVER 2005映象實驗SQLServer
- SQL Server 2005 Express Edition 概述SQLServerExpress
- SQL Server 2005:清空plan cacheSQLServer
- SQL Server 2005中修改 Server Collation的方法SQLServer
- Service Worker初探
- SQL Server Service Pack Model and Naming RuleSQLServer
- sql server 2005資料庫快照SQLServer資料庫
- 配置SQL Server 2005伺服器SQLServer伺服器
- SQL SERVER 2005表分割槽功能SQLServer
- SQL Server 2005動態管理物件SQLServer物件
- 實戰 SQL Server 2005 映象配置SQLServer
- Sql server 2005中output用法解析SQLServer
- Sql Server 2005 日誌壓縮SQLServer
- SQL SERVER 2005 日誌收縮SQLServer
- sql server 2005使用點滴(1)SQLServer
- SQL Server 2005 Cluster 叢集部署SQLServer
- SQL Server 2005鎖的問題SQLServer
- 已安裝 SQL Server 2005 Express 工具。若要繼續,請刪除 SQL Server 2005 Express 工具SQLServerExpress
- SQL Server 2005效能調整二(zt)SQLServer
- SQL Server 2005效能調整一(zt)SQLServer
- 清除 SQL SERVER 2005 事務日誌SQLServer