訊息、承載和序列化

Azure 服務匯流排的功能就是處理訊息。 訊息包含承載和中繼資料。 中繼資料會以機碼值組的形式描述承載,並對服務匯流排和應用程式提供處理指示。 偶爾只要該中繼資料就足夠可承載傳送者需要與接收者通訊的資訊,且承載會維持空白。

.NET 和 Java 的正式服務匯流排用戶端物件模型會反映抽象服務匯流排訊息結構,其會對應往返線路通訊協定服務匯流排支援。

服務匯流排訊息包含二進位承載區段 (服務匯流排決不會在服務端以任何形式進行處理),以及包含兩組屬性。 訊息代理程式屬性是由系統預先定義。 這些預先定義的屬性會控制訊息代理程式內的訊息層級功能,或是會對應至一般和標準化項目。 使用者屬性是機碼/值組的集合,可由應用程式進行定義及設定。

下表列出預先定義的訊息代理程式屬性。 所有官方用戶端 API 均會使用這些名稱,同時也會在 HTTP 通訊協定對應的 BrokerProperties JSON 物件中使用。

括弧中列出 AMQP 通訊協定層級所使用的對等名稱。 雖然下列名稱使用 Pascal 命名法的大小寫慣例,但請注意,JavaScript 和 Python 用戶端會分別使用駝峰式和蛇形命名法的大小寫形式。

屬性名稱 描述
ContentType (內容-類型) 選擇性地說明訊息的承載,並提供遵循 RFC2045 第 5 節格式的描述項;例如 application/json
CorrelationId (相互關聯識別碼) 讓應用程式能夠指定訊息的內容以供相互關聯之用;例如,反映正要回覆之訊息的 MessageId
DeadLetterSource 只會設定於已成為無效信件,且之後會從無效信件佇列自動轉送到另一個實體的訊息中。 指示其中訊息已成為無效信件的實體。 這個屬性是唯讀的。
DeliveryCount

針對此訊息嘗試進行的傳遞次數。 當訊息鎖定到期時或接收者明確放棄此訊息時,這個計數就會遞增。 這個屬性是唯讀的。

當基礎 AMQP 連線關閉時,傳遞計數不會遞增。

EnqueuedSequenceNumber 對於已自動轉送的訊息,這個屬性會反映訊息在提交原始點時,首次指派給訊息的序號。 這個屬性是唯讀的。
EnqueuedTimeUtc 在實體中接受並儲存訊息的 UTC 時刻。 當接收者不信任傳送者的時鐘時,這個值可用來作為權威且中立的抵達時間指標。 這個屬性是唯讀的。
Expires​AtUtc (絕對到期時間) 由於到期而將訊息標示為移除,且無法再從實體中擷取的 UTC 時間。 到期會由 TimeToLive 屬性所控制,而這個屬性會從 EnqueuedTimeUtc + TimeToLive 計算而得。 這個屬性是唯讀的。
LabelSubject (主旨) 這個屬性可讓應用程式以標準化方式向接收者指出訊息目的,類似於電子郵件主旨行。
Locked​Until​Utc 對於在鎖定下接收的訊息 (查看鎖定接收模式,不是預先安置的),這個屬性反映訊息會維持鎖定在佇列/訂用帳戶中的結束 UTC 時刻。 當鎖定到期時,DeliveryCount 就會遞增,而訊息就再次可供擷取。 這個屬性是唯讀的。
Lock​Token 鎖定權杖是「查看鎖定」接收模式中由訊息代理程式所持有鎖定的參考。 權杖可透過延遲 API 以將鎖定永久固定,然後從一般傳遞狀態流程中取出訊息。 這個屬性是唯讀的。
Message​Id (訊息識別碼) 訊息識別碼是應用程式定義的值,可唯一識別訊息及其承載。 識別碼是一個自由格式的字串,可以反映 GUID 或衍生自應用程式內容的識別碼。 如果啟用重複偵測功能,就可以識別並移除具有相同 MessageId 之訊息的第二次及後續提交。
Partition​Key 針對分割的實體,設定此值可將相關訊息指派到相同的內部資料分割,如此便能正確記錄提交順序。 資料分割無法直接選擇,而是由雜湊函式透過這個值來決定。 對於工作階段感知的實體,SessionId 屬性會覆寫此值。
Reply​To (回覆對象) 這個選擇性且由應用程式定義的值,乃是向訊息接收者表示回覆路徑的標準方法。 當傳送者預期收到回覆時,會將值設為預期回覆要送往的佇列或主題絕對或相對路徑。
Reply​To​Session​Id (回覆至群組識別碼) 這個值可以擴充 ReplyTo 資訊,並指定在傳送到回覆實體時針對回覆所應設定的 SessionId
Scheduled​Enqueue​Time​Utc 對於僅能在延遲之後可供擷取的訊息,這個屬性會定義以邏輯方式將訊息加入佇列、排序,並使其可供擷取的 UTC 時刻。
Sequence​Number 序號是指派給訊息的唯一 64 位元整數,會由訊息代理程式和函式所接收並儲存,以作為真正的識別碼。 對於分割的實體,最前面的 16 位元會反映分割區識別碼。 序號會以無間斷方式循序遞增。 它們會在 48 - 64 位元範圍用盡時回復為 0。 這個屬性是唯讀的。
Session​Id (群組識別碼) 對於工作階段感知的實體,這個應用程式定義的值會指定訊息的工作階段關係。 具有相同工作階段識別碼的訊息會受限於摘要鎖定,並且能夠確實地依序處理和分離信號。 非工作階段感知的實體會忽略這個值。
Time​To​Live 這個值是訊息到期前的相對持續期間,從訊息代理程式接受並儲存的瞬間開始,正如 EnqueueTimeUtc 所擷取的時間。 未明確設定時,所使用的值便是對應佇列或主題的 DefaultTimeToLive。 訊息層級的 TimeToLive 值不能比實體的 DefaultTimeToLive 設定還長。 如果較長,則會以無訊息方式調整。
To (至) 這個屬性會保留以便日後供路由傳送案例使用,訊息代理程式目前會忽略這個屬性。 應用程式可在規則驅動的自動轉送鏈結案例中使用這個值,指出訊息預期的邏輯目的地。
Via​Partition​Key 如果訊息會透過交易範圍內的傳輸佇列來傳送,這個值就會選取傳輸佇列資料分割。

抽象訊息模型可讓訊息透過 HTTPS 發佈至佇列,並且讓訊息透過 AMQP 來擷取。 不論是何種狀況,訊息在對應通訊協定的內容中看起來都很正常。 訊息代理程式屬性會視需要加以轉譯,使用者屬性也會對應至相對通訊協定訊息模型上最適當的位置。 在 HTTP 中,使用者屬性會直接與 HTTP 標頭相互對應;在 AMQP 中,使用者屬性則會與 application-properties 對應相互對應。

訊息路由傳送及相互關聯

先前提及的一部分訊息代理程式屬性,尤其是 ToReplyToReplyToSessionIdMessageIdCorrelationIdSessionId,用來協助應用程式將訊息路由傳送至特定目的地。 為了進一步說明這項功能,請考慮以下幾個模式的情況:

  • 簡單要求/回覆:發行者將訊息傳送至佇列,然後期待訊息取用者的回覆。 如需接收回覆,發行者需擁有其回覆預期要遞交的目的地佇列。 該佇列的位址會以輸出訊息的 ReplyTo 屬性來表示。 當取用者回應時,會將已處理訊息的 MessageId 複製到回覆訊息的 CorrelationId 屬性,並將訊息傳遞到 ReplyTo 屬性所指示的目的地。 一個訊息可能會產生多個回覆,視應用程式內容而定。
  • 多點傳送要求/回覆:前一種模式的變化,發行者將訊息傳送至主題,而多個訂閱者變成有資格取用訊息。 每個訂閱者可能會以先前所述的方式回應。 探索或復原通話案例中會使用此模式,且受訪者通常會以使用者屬性或在承載內識別其身分。 如果 ReplyTo 指向主題,就能將這類探索回應散發給目標對象。
  • 多工:此工作階段功能可透過單一佇列或訂用帳戶,啟用相關訊息的多工作業,使得特定接收者將工作階段維持鎖定之際,相關訊息的每個工作階段或群組 (藉由符合的 SessionId 值來識別) 會路由傳送給接收者。 如需工作階段的詳細資料,請在這裡進行深入了解。
  • 多工要求/回覆:此工作階段功能啟用多工回覆,可讓多個發行者共用一個回覆佇列。 發行者可以設定 ReplyToSessionId,以指示取用者將該值複製到回覆訊息的 SessionId 屬性。 發佈佇列或主題無須感知工作階段。 傳送訊息時,發行者接著可以有條件地接受工作階段接收者,以特地等候佇列上具有指定 SessionId 的工作階段具體化。

在服務匯流排命名空間內進行路由傳送,可以使用自動轉送鏈結和主題訂閱規則來實現。 在命名空間之間進行路由傳送,可以使用 Azure LogicApps 來實現。 如同上述清單中所述,To 屬性會保留以供日後使用,且最終會由訊息代理程式藉由特別啟用的功能來解譯。 希望實作路由傳送的應用程式應該根據使用者屬性來執行此動作,而非依賴 To 屬性,不過,此方式目前並不會造成相容性問題。

承載序列化

承載在傳輸中或儲存在服務匯流排內時,一律為不透明的二進位區塊。 ContentType 屬性可讓應用程式描述承載,根據 IETF RFC2045,建議的屬性值格式為 MIME content-type 描述,例如 application/json;charset=utf-8

與 Java 或.NET 標準變數不同,服務匯流排 API 的 .NET Framework 版本支援將任意 .NET 物件傳遞到建構函式來建立 BrokeredMessage 執行個體。

在 2026 年 9 月 30 日,我們將淘汰不符合 Azure SDK 準則的 Azure 服務匯流排 SDK 程式庫 WindowsAzure.ServiceBus、Microsoft.Azure.ServiceBus 和 com.microsoft.azure.servicebus。 我們也將結束 SBMP 通訊協定的支援,因此您將無法在 2026 年 9 月 30 日之後再使用此通訊協定。 請在該日期之前移轉至最新的 Azure SDK 程式庫,該程式庫提供重要的安全性更新和改進的功能。

雖然較舊的程式庫仍可在 2026 年 9 月 30 日之後使用,但這些程式庫將無法繼續收到 Microsoft 的官方支援和更新。 如需詳細資訊,請參閱支援淘汰公告

使用舊版 SBMP 通訊協定時,接著會使用預設的二進位序列化程式將物件序列化,或是使用外部提供的序列化程式進行序列化。 將物件序列化為 AMQP 物件。 接收者可以利用 GetBody<T>() 方法擷取物件並提供預期型別。 透過 AMQP,物件序列化為 ArrayListIDictionary<string,object> 物件的 AMQP 圖表,而且可由任何 AMQP 用戶端解碼。

2026 年 9 月 30 日我們將淘汰 Azure 服務匯流排的 SBMP 通訊協定支援,因此您將無法在 2026 年 9 月 30 日之後再使用此通訊協定。 請在該日期之前移轉至使用 AMQP 通訊協定的最新 Azure 服務匯流排 SDK 程式庫,該程式庫提供重要的安全性更新和改進的功能。

如需詳細資訊,請參閱支援淘汰公告

儘管這項隱藏的序列化魔術很便利,但應用程式應明確控制物件序列化,並在訊息內包含這些應用程式之前,將其物件圖轉換為串流,並在接收者端進行反轉。 這會產生互通結果。 當 AMQP 具有功能強大的二進位編碼模型時,系統會將它繫結到 AMQP 傳訊生態系統,而 HTTP 用戶端將在為這類承載進行解碼時遇到問題。

.NET 標準和 Java API 變數只接受位元組陣列,這表示應用程式必須處理物件序列化控制。

如果無法還原序列化訊息的承載,則建議使訊息成為無效信件

下一步

若要深入了解服務匯流排傳訊,請參閱下列主題: