首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 數據庫知識 >  >> SQL Server 資料庫 >> 關於SqlServer

SQL Server Service Broker (SSB) 入門實戰:從架構概念到異步消息處理全流程

     編輯:關於SqlServer

什麼是 Service Broker?

SSB 是 SQL Server 內建的**異步消息隊列框架**,支援可靠傳輸、事務一致性、跨實例路由。適用於:異步業務解耦、跨庫/跨服務器數據同步、長時間任務排隊、事件驅動架構。

核心對象體系

  1. Message Type:定義消息格式(XML/二進制/空)。
  2. Contract:規定雙向消息類型與發送方角色。
  3. Queue:消息持久化存儲容器(本質是隱藏表)。
  4. Service:綁定 Queue + Contract,對外暴露端點。
  5. Dialog Conversation:會話通道,保證有序、一次性投遞。

實戰:庫存異步更新示例

Step 1:建庫建表

USE master; GO
CREATE DATABASE Inventory; GO
USE Inventory; GO
CREATE TABLE InventoryTbl (TitleId NVARCHAR(6) NOT NULL, Quantity INT NOT NULL, PRIMARY KEY(TitleId,Quantity));
INSERT InventoryTbl VALUES ('PC1001',100),('PC1002',200),('PC1003',300),('PC1004',400);

Step 2:創建 SSB 基礎設施

-- 消息類型
CREATE MESSAGE TYPE [//mark/v10/types/inventory] VALIDATION = WELL_FORMED_XML;
CREATE MESSAGE TYPE [//mark/v10/types/inventoryresponse] VALIDATION = WELL_FORMED_XML;

-- 合約:發起方發 inventory,目標方回 inventoryresponse
CREATE CONTRACT [//mark/v10/contracts/inventorycontract]
    ([//mark/v10/types/inventory] SENT BY INITIATOR,
     [//mark/v10/types/inventoryresponse] SENT BY TARGET);

-- 隊列與服務
CREATE QUEUE [InventoryClientQueue];
CREATE SERVICE [//mark/v10/services/inventoryclient] ON QUEUE [InventoryClientQueue];

CREATE QUEUE [InventoryQueue];
CREATE SERVICE [//mark/v10/services/inventory] ON QUEUE [InventoryQueue]
    ([//mark/v10/contracts/inventorycontract]);

Step 3:發送消息(發起方)


BEGIN TRAN;
DECLARE @dialog UNIQUEIDENTIFIER;
BEGIN DIALOG CONVERSATION @dialog
    FROM SERVICE [//mark/v10/services/inventoryclient]
    TO SERVICE '//mark/v10/services/inventory'
    ON CONTRACT [//mark/v10/contracts/inventorycontract]
    WITH ENCRYPTION = OFF;

SEND ON CONVERSATION @dialog MESSAGE TYPE [//mark/v10/types/inventory]
(
    N'
        PC1001
        102
      '
);
COMMIT TRAN;

Step 4:接收處理(目標方,手動演示)


BEGIN TRAN;
DECLARE @dialog UNIQUEIDENTIFIER, @msg XML, @qty INT, @title NVARCHAR(128);

RECEIVE TOP(1)
    @dialog = conversation_handle,
    @msg = message_body
FROM [dbo].[InventoryQueue];

IF @dialog IS NOT NULL
BEGIN
    SET @qty = @msg.value('(/InventoryUpdate/Quantity)[1]','INT');
    SET @title = @msg.value('(/InventoryUpdate/TitleId)[1]','NVARCHAR(100)');
    UPDATE InventoryTbl SET Quantity = @qty WHERE TitleId = @title;
    END CONVERSATION @dialog;
END
COMMIT TRAN;

Step 5:自動化監聽 —— 隊列激活


-- 1. 創建處理存儲過程
CREATE PROC InventoryProc AS
BEGIN
    SET NOCOUNT ON;
    DECLARE @dialog UNIQUEIDENTIFIER, @msg XML, @qty INT, @title NVARCHAR(128);

    WAITFOR (
        RECEIVE TOP(1)
            @dialog = conversation_handle,
            @msg = message_body
        FROM [dbo].[InventoryQueue]
    ), TIMEOUT 5000;  -- 5 秒無消息則退出

    IF @dialog IS NOT NULL
    BEGIN
        SET @qty = @msg.value('(/InventoryUpdate/Quantity)[1]','INT');
        SET @title = @msg.value('(/InventoryUpdate/TitleId)[1]','NVARCHAR(100)');
        UPDATE InventoryTbl SET Quantity = @qty WHERE TitleId = @title;
        END CONVERSATION @dialog;
    END
END;
GO

-- 2. 啟用隊列激活
ALTER QUEUE [InventoryQueue]
WITH ACTIVATION (
    STATUS = ON,
    PROCEDURE_NAME = InventoryProc,
    MAX_QUEUE_READERS = 2,  -- 並發消費者數
    EXECUTE AS SELF
);
GO

自此,**只要有消息進隊列,SQL Server 自動並發啟動 InventoryProc 處理**,無需外部輪詢服務。

驗證與監控

  • 查看隊列積壓:SELECT * FROM [InventoryQueue];
  • 查看客戶端隊列確認消息:SELECT message_type_name FROM [InventoryClientQueue];
  • 系統視圖:sys.conversation_endpoints、sys.transmission_queue 監控會話狀態、傳輸隊列。

生產環境關鍵配置

項目建議
加密跨實例必開 WITH ENCRYPTION = ON,需憑證/主鑰體系
持久化隊列本質是表,受數據庫備份/恢復保護,消息不丟失
錯誤處理存儲過程內 TRY...CATCH,失敗可 ROLLBACK 讓消息回隊列重試
有序性同一會話保證順序;不同會話並行,業務需自行設計分區鍵
清理策略定期 END CONVERSATION 清理已結束會話,防止 sys.conversation_endpoints 膨脹

結語

SSB 將「消息中間件」內建進數據庫引擎,以事務為邊界實現**業務與消息原子性**,省去 Kafka/RabbitMQ 運維成本。掌握「類型→合約→隊列→服務→會話→激活」六步走,即可在 SQL Server 內構建企業級異步架構。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved