當一個節點發送像這樣的方法幀時,它總是會遵循一個內容頭幀(conent header frame)和零個或多個內容體幀(content body frame)的形式.
當一個節點發送像這樣的方法幀時,它總是會遵循一個內容頭幀(conent header frame)和零個或多個內容體幀(content body frame)的形式.
一個內容頭幀有下面的格式:

我們將內容體放置在不同的幀中(并不包含在方法中),因此AMQP可支持零拷貝技術,這樣其內容就不需要編組或編碼. 我們將內容屬性安放在它們自己的幀中,以便收件人可以有選擇地丟棄他們不想處理的內容。
2.3.5.3 心跳幀
心跳是一種設計用來撤銷(undo)TCP/IP功能的技術,也就是說在長時間超時后,它有能力通過關閉broker物理連接來進行恢復.在某些情景下,我們需要快速知道節點連接是否斷開了,或者是由于什么原因不能響應了.因為心跳可以在較低水平上進行,我們在傳輸層次上按節點交換的特定幀類型來處理,而不是按類方法.
2.3.6 錯誤處理
AMQP使用異常來處理錯誤.任何操作錯誤(未找到消息隊列,訪問權限不足)都會導致一個通道異常. 任何結構化的錯誤(無效參數,壞序列的方法.)都會導致一個連接異常.異常會關閉通道或連接,同時也會向客戶端應用返回響應碼和響應文本.我們使用了類似于HTTP等協議和其它大多數協議中的三位回復代碼和文字回復文本方案.
2.3.7 關閉通道和連接
連接或通道,對于客戶端來說,當其發送Open時則被認為是“打開”的,對于服務器端來說,當其發送Open-Ok時則被認為是打開的。基于這一點,一個希望關閉通道或連接的對等體也必須使用握手協議來這樣做。
可出于任何原因,可能會正常地或異常地關閉一個通道或連接-因此必須仔細小心。
對于突然或意外關閉,并不能得到快速探測,因此當發生異常時,我們可能會丟失錯誤回復代碼。
正確的設計是對于所有關閉必須進行握手,使我們關閉后對方知道相應的情況。
當一個節點決定關閉一個通道或連接時,它發送一個Close方法。接收節點必須使用Close-Ok來響應Close,然后雙方可以關閉他們的通道或連接。請注意,如果節點忽略了關閉,當兩個節點同時發送Close時,可能會發生死鎖。
2.4 AMQP Client 架構
可直接從應用程序中讀寫AMQP幀,但這是相當糟糕的設計.
即使是最簡單的對話框也比較復雜(比如同HTTP比較),應用程序開發者沒必要為了向消息隊列發送消息, 而來理解二進制這樣的東西. 推薦的AMQP client架構須由下面的多個抽象層組成:
1. 幀層. 此層接受AMQP協議方法,并按某種語言格式(結構,類等等) 來序列化成線路級幀.幀層可以根據AMQP規范機械產生(這是在一個協議的建模語言,專為AMQP定義了XML實現).
2. 連接管理層. 此層用于讀寫AMQP幀,并管理所有連接,會話邏輯.在此層中,我們可以封裝打開連接和會話,錯誤處理,內容傳輸和接收的全部邏輯. 此層的大部分都可通過AMQP規范來生成.例如,規范定義了哪些方法可以攜帶內容, 因為邏輯發送方法和可選的發送內容可以機械的生成.
3. API 層. 此層暴露了應用程序工作的特定API. API層可能會反映一些現有的標準,或暴露高層AMQP的方法,或對本節前面介紹的內容做一個映射。AMQP方法設計為使這些映射簡單有用。API層本身可能是由多個層組成的,如.構建于AMQP方法API之上的高級API.
此外,通常還會有一些I / O層,這此可以是非常簡單的(同步套接字讀取和寫入)或復雜的(完全異步多線程I / O)。此圖顯示了整體推薦的架構:

在本文檔中,當我們說"client API"的時候,我們指的則是應用程序下的所有層(i/o,幀,連接按理和API層).我們通常將客戶端API和應用程序分開說, 在這里,應用程序會使用客戶端API來同中間件服務器進行對話.
3 功能說明
3.1 Server 功能說明
3.1.1 消息和內容
消息是中間件路由和隊列系統處理的原子單元。消息可攜帶一份內容,它包括一個內容頭,一組屬性,和一個內容體,和持有一個不透明的二進制數據塊。
一個消息可以對應到許多不同應用程序的實體:
一個應用程序級消息
一個傳輸文件
一個數據流幀等等.
消息可以持久化.一個持久化消息可以安全地存儲在磁盤上,即使是在嚴重的網絡故障,服務器崩潰、溢出等情況下也可確保投遞.消息也可以有優先級.高優先級消息會在等待同一個消息隊列時,在低優先級消息之前發送. 當消息必須被丟棄以確保服務器質量水平,將會優先丟棄低優先級消息.
服務器不能修改接收到并將傳遞給消費者應用程序的消息內容體. 服務器可在內容頭中添加額外信息,但不能刪除或修改現有信息.
3.1.2 虛擬主機(Virtual Hosts)
虛擬主機是服務器內的數據分區, 它為在共享基礎設施上的管理帶來了方便.
一個虛擬主機包括其命名空間,一組交換器,消息隊列以及所有相關對象. 每個連接必須關聯一個單個虛擬主機.
在認證后,客戶端可在Connection.Open方法中選擇虛擬主機. 這意味著,服務器上的認證方案可在此服務器上的所有虛擬主機上共享. 然而,對于每個虛擬主機來說,也可以獨特的認證方案. 對于每個虛擬主機需要不同的身份驗證方案的管理員應該使用單獨的服務器。
連接中的所有通道都在同一個虛擬主機上工作.在同一個連接中,沒有與不同虛擬主機通信的方式, 也沒有在不斷開連接重新開始的情況下,切換到其它虛擬主機的可能性.
該協議沒有提供用于創建或配置虛擬主機的機制-這在服務器內是一個不確定的方式,是完全依賴于實現的。
3.1.3 交換器
交換器是一個虛擬主機內的消息路由代理。交換器實例(我們通常稱之為“交換器”)接受消息和路由信息-主要是一個路由鍵-或者將消息傳遞到消息隊列,或到內部服務。交換器是基于每個虛擬主機命名的。
應用程序可以在權限范圍內自由地創建、共享、使用和銷毀交換器實例.交換器可能是持久的、臨時的或自動刪除的。持久化的交換器會持續到他們被刪除,臨時的交換器會持續到服務器關閉。自動刪除的交換器直到他們不再使用。服務器提供了一組特定的交換器類型。每個交換器類型都實現了一個特定的匹配和算法,如下一節中定義的。AMQP只要求少量的交換器類型,并推薦了一些。此外,每個服務器實現可以添加自己的交換類型。
交換器可以將單個消息并發地路由到的消息隊列中。這將創建一個獨立消息的多個實例。
3.1.3.1 Direct交換器類型
direct 交換器按如下方式來工作:
1. 消息隊列使用路由鍵K來綁定交換器.
2. 發布者使用路由鍵R來向交換器發送消息.
3. 在K=R時,消息會傳遞到消息隊列中.
server必須實現direct交換器,并且在每個虛擬主機中必須預定義兩個direct交換器: 一個名為 amq.direct, 另一個無公共名稱(為Publish方法的默認交換器).
注意,消息隊列可以使用任何有效的路由鍵值進行綁定,但通常消息隊列使用它們自己的名稱作路由鍵來綁定.
事實上,所有消息隊列必須能使用其自身隊列名稱作路由鍵自動綁定無名稱的交換器上.
3.1.3.2 Fanout 交換器類型
fanout交換器類型按如下方式來工作:
1. 消息隊列不使用參數來綁定交換器.
2. 發布者向交換器發送消息.
3. 消息無條件傳遞給消息隊列。
fanout 交換器是微不足道的設計與實現.此交換器類型和預聲明的交換器稱為amq.fanout,它是強制的.
3.1.3.3 Topic交換器類型
topic交換器類型按如下方式來工作:
1. 消息隊列使用路由模式P來綁定到交換器.
2. 發布者使用路由鍵R來向交換器發送消息.
3. 當R匹配P時,消息將被傳遞到消息隊列.
用于topic交換器的路由鍵必須由0個或多個由點號
用于topic交換器的路由鍵必須由點分隔的零或多個單詞組成.每個單詞必須包含字母A-Z和a-z 以及數字0-9.
路由模式與路由鍵遵循相同的規則,* 用于匹配單個單詞,# 用于匹配0個或多個單詞.因此路由模式*.stock.# 會匹配路由鍵usd.stock 和eur.stock.db 但不匹配stock.nasdaq.
對于topic交換器我們建議的設計是保持所有已知路由鍵的集合,當發布者使用了新的路由鍵時,才更新此集合. 通過給定一個路由鍵來確實所有綁定是可能的,因此可為消息快速找到消息隊列. 此交換器類型是可選的.
server應該實現topic交換器類型,在這種情況下,server 必須在每個虛擬主機中預先定義至少一個 topic交換器,其名稱為amq.topic.
3.1.3.4 Headers交換器類型
headers交換器類型按如下方式進行工作:
1. 消息隊列使用包含匹配綁定和帶有默認值的header參數表來綁定交換器.在這種交換器類型中,不使用路由鍵.
2.發布者向交換器發送消息,這些消息的headers屬性中包含名稱-值對的表.
3.如果消息頭屬性與隊列綁定的參數相匹配,則消息傳遞給隊列。
匹配算法是由參數表中的名稱值對這樣的特殊綁定參數來控制的. 這個參數的名稱是'x-match'.
它可以接受兩種值, 以表示表格中其它的名稱值對將如何來進行匹配:
'all' 則表明所有其它的名稱值對必須與路由消息的頭屬性相匹配(即.AND匹配)
'any' 則表明只要消息頭屬性中的任何一個字段匹配參數表中的字段,則消息就應該被路由(即. OR匹配).
綁定參數中的字段必須與消息字段中的字段相匹配,這些情況包括:如果綁定參數中的字段沒有值且在消息頭中存在相同名稱的字段,或者綁定參數中的字段有值,且消息屬性中存在同樣的字段且有相同的值。
任何以'x-'而不是'x-match'開頭的字段為將來保留使用并會被忽略.
server應該實現headers交換器類型, 且server必須在每個虛擬主機中預先聲明至少一個headers交換器,且名稱為amq.match.
3.1.3.5 System交換器類型
system交換器類型按如下方式進行工作:
1. 發布者使用路由鍵S來向交換器發送消息.
2. system交換器將其傳遞給系統服務S.
系統服務以"amq."開頭,為AMQP保留使用. 在服務器環境中,所有其它名稱可自由使用. 此交換器類型是可選的.
3.1.3.6 實現定義的交換器類型
所有非規范交換器類型必須以"x-"開頭. 不以"x-"開頭的交換器作為將來AMQP標準保留使用.
3.1.4 消息隊列
消息隊列是一個名為FIFO的緩沖區且為一組消費者應用程序保存消息.
在其權限范圍內,應用程序可以自由地創建、共享、使用和銷毀消息隊列.
注意,在一個隊列中可能存在多個讀者,或存在客戶端事務,或存在使用了優先級字段,或存在使用了消息選擇器,或特定實現了投遞優化的隊列可能不會真正地展現出FIFO特性. 唯一可以確保FIFO的方式是只有一個消費者連上了隊列.在那些情況下,隊列可描述為弱-FIFO.
消息隊列可能是持久化的或自動刪除的.持久化消息隊列會持續到它們刪除時為止. 臨時消息隊列可持續到服務器關閉時為止.自動刪除消息隊列可持續到它們不再使用時為止.
Message隊列可將消息存儲在內存,磁盤,或兩者的組合中.消息隊列是基于虛擬主機來命名的.
消息隊列保存信息,并可在一個或多個消費客戶端之間進行分發.路由到消息隊列中的消息不能再發給多個客戶端,除非在失敗或拒絕后進行重發.
單個消息隊列可在同個時間可獨立地持有不同類型的內容.也就是,如果Basic和文件內容都發給了同一個消息隊列,這些將會作為請求獨立地分發給消費應用程序.
3.1.5 綁定
綁定是消息隊列和交換器之間的關系.綁定特有的路由參數將告訴交換器那些隊列應該得到消息. 應用程序可根據需要來驅動消息流向它們的消息隊列. 綁定的壽命依賴于定義它們的消息隊列 - 當消息隊列被銷毀時,其綁定也會被銷毀.Queue.Bind 方法的特定語義將依賴于交換器類型.
3.1.6 消費者
我們使用術語"consumer"來表示應用程序和控制客戶端程序來接收消息隊列中的實體.當客戶端啟動一個消費者,它就在服務器中創建了一個消費實體 .當客戶端退出一個消費者時,它就銷毀了一個服務器中的消費者實體. 屬于單個客戶端通道的消費者可異步地將消息發送到隊列中.
3.1.7 服務質量
服務質量控制了消息發送的速度. 服務質量依賴于被分發的內容類型.一般的服務質量,在客戶端應答消息前,會使用預提取的概念來指定發送多少個消息或多少個字節的數量. 目標是提前發送消息數據,以減少延遲。
3.1.8 確認/應答
應答是從客戶端程序發出的正式信號,用以表示消息隊列中的消息已經得到成功處理. 有兩種應答模型:
1. 自動地(Automatic), 在這種情況下,只要消息投遞到了應用程序,服務器就會立即從消息隊列中刪除消息(通過 Deliver 或 Get-Ok 方法).
2. 明確地(Explicit),在這種情況下,客戶端程序必須對每個消息發磅一個Ack方法以表示消息被處理了.客戶端層可以不同方式來實現明確應答,如.只要收到了消息或當應用程序表示消息已經處理了.
這些區別不會影響AMQP或互操作性.
3.1.9 流控制(Flow Control)
流控制是一個用來中止節點消息流的緊急過程. 它在客戶端和服務器端都按同樣方式工作,且都是由Channel.Flow命令實現的. 流控制是唯一可以阻止一個過度生產發布者的機制.如果它使用消息確認(這通常意味著使用事務), 消費者則可以使用更優雅的預取機制窗口。
3.1.10 命名約定
這些約定規范了AMQP實體命名. 服務器和客戶端必須遵守這些約定:
用戶定義的交換器類型前輟必須是"x-"
標準交換器實例前輟是"amq."
標準系統服務前輟是"amq."
標準消息隊列前輟是"amq."
所有其他的交換器、系統服務和消息隊列名稱都在應用程序空間中。
3.2 AMQP 命令說明(Classes & Methods)
3.2.1 解釋性注釋
出于互操作原因,AMQP方法可以定義特定的最小值(如每消息隊列的消費者數量)。這些極小值被定義在每個類的描述中。
遵從AMQP的實現應該為這些字段實現合理值, 最小值只用在最小能力的平臺上.
語法使用這樣的標記法:
'S:' 指示從服務器發送到客戶端的數據或方法;
'C:' 指示從客戶端發送到服務器的數據或方法;
+term or +(...) 表達式表示1個或多個實例;
*term or *(...) 表達式表示0個或多個實例.
我們定義的方法是:
一個同步請求("syn request").發送節點應該等待特定的回復方法,但可以異步實現此方法;
一個同步回復("syn reply for XYZ");
一個異步請求或答復 ("async").
3.2.2 類和方法細節
這部分是由生成的文件amqp-xml-spec.odt提供。
4 技術說明
4.1 IANA分配的端口號
IANA為標準AMQP的TCP和UDP分配了5672端口。UDP端口被保留用于將來的組播實現。
4.2 AMQP 線程級格式
4.2.1 正式協議語法
我們為AMQP提供了一個完整語法(這只是AMQP提供的參考,跳到下一節,你會發現不同的幀類型和格式):


我們使用了IETF RFC 2234中定義的增強BNF語法. 總體而言,
規則的名稱僅僅是名稱本身。
終端是由一個或多個數字字符指定的,這些字符的基本解釋為“d”或“x”。
通過列出一系列規則名稱,一個規則可以定義一個簡單的,有序的字符串的值.
其他數值的范圍可以簡潔指定,使用破折號(“-”)來表示替代值的范圍。
在圓括號中的元素被視為單個元素,其內容是嚴格有序的。
由/分隔的元素是可替代值.
元素之間的操作符 "*"表示重復.完整格式為: "<a>*<b>element",這里<a>的<b>是可選的十進制值, 表示只能出現大于<a>而小于<b>的元素.
規則形式: "<n>element" 等價于<n>*<n>element.
方括號中的元素是可選元素.
4.2.2 協議頭
client必須通常發送一個協議頭開始新連接.它是8字節序列:

協議頭由大寫字母"AMQP",其后跟常量%d0組成:
1. 協議主版本號, 按照章節1.4.2中描述的使用.
2. 協議次版本號, 按照章節1.4.2中描述的使用.
3. 協議修訂版本, 按照章節1.4.2中描述的使用.
該協議協商模型與現有HTTP協議兼容,使用常量文本字符串來發起連接, 并使用防火墻來檢測協議的開始以決定應用什么規則.
client和服務通過以下方式來達成協議版本一致:
client打開一個到AMQP服務器的新socket連接,并發送協議頭.
server可接受或拒絕協議頭.如果它拒絕了協議頭,它將會輸出一個有效的協議頭到socket,然后再關閉socket.
否則它會同意(leaves)socket打開,并相應地實現協議.
示例:

實現者指導方針:
server可接受非AMQP協議,如HTTP.
如果server無法識別socket數據中的前5個字節,或者它不支持client請求的協議版本,它必須輸出一個有效的協議頭到socket,然后再關閉socket (必須確保client應用程序能收到數據) ,最后再關閉socket連接.服務器可以打印診斷信息以輔助調試。
client可使用服務器支持的最高版本來進行檢測,如果收到了服務器發回的這種信息,就可使用較低版本來進行重連
實現了多版本AMQ的Clients和servers都應該使用8字節的協議頭來標識協議.
4.2.3 通用幀格式
所有幀都以7個字節的頭開始,其中包括一個type字段 ,一個channel字段和一個size字段:

AMQP 定義了如下的幀類型:
Type = 1, "METHOD": 方法幀
Type = 2, "HEADER": 內容頭幀
Type = 3, "BODY": 內容體幀.
Type = 4, "HEARTBEAT": 心跳幀.
通道編號為0的代表全局連接中的所有幀,1-65535代表特定通道的幀.
size字段是負載的大小,不包括結束幀字節. 由于AMQP假設是一個可靠的連接協議,我們使用結束幀來檢測錯誤客戶端和服務器實現引起的錯誤.
實現者指導方針:
結束幀必須是十六進制值%xCE.
如果一個節點收到了未定義類型的幀,它必須將其視為致命的協議錯誤,并關閉連接,而不進一步地發送任何數據
當一個節點讀取到幀時,在解碼幀前,它必須檢查結束幀是否是有效的. 如果結束幀無效,它必須將其視為致使的協議錯誤,并關閉連接,而不進一步地發送任何數據. 它應該記錄相關問題的日志信息,這樣就可以服務器或客戶端幀代碼實現中表示錯誤.
節點發送的幀大小不能超過約定的大小. 節點收到超過大小的幀時,必須發出一個回復碼為501(幀錯誤)的連接異常信號.
對于所有心跳幀,方法幀,連接類的頭和體,通道編號必須為0. 節點收到非0通道編號的這些幀必須使用回復碼503(無效命令)來發出異常信號.
4.2.4 方法負載
方法幀的體包括一個不可變的數據字段列表,稱為"arguments".所有方法體都以類型和方法的標識符開始:

實現者指導方針:
class-id 和 method-id是由AMQP類和方法定義的常量.
arguments 是特定于每個方法中的一組AMQP字段.
Class id 中%x00.01-%xEF.FF范圍內的值被AMQP標準類保留使用.
Class id 中%xF0.00-%xFF.FF (%d61440-%d65535) 范圍內的值可用于非標準擴展類實現.
4.2.5 AMQP 數據字段
AMQP有兩種級別的數據字段:用于方法參數的原生數據字段, 以及用于多個應用之間傳遞數據的字段表. 字段表是原生數據字段的超集.
4.2.5.1 Integers
AMQP定義了這些原生整數類型:
無符號字節(8 bits).
無稱號短整形(16 bits).
無符號長整形(32 bits).
無符號長長整形(64 bits).
整形和字符串長度總是無符號的,且按網絡字節順序保存. 當存在兩個高低系統時(如.兩個Intel CPUS),我們不會對它們的交互嘗試優化.
實現方針:
實現不能假設幀內的整形編碼在內存邊界中是對齊的.
4.2.5.2 Bits
AMQP定義了一個原生位字段類型. 位累積成整個字節. 當在幀中兩個或更多位相鄰時,它們會被包裝成一個或多個字節,且在每個字節中以低位開始.
沒有要求在一個幀中的所有位必須是連續的,但這通常是做,以盡量減少幀尺寸。
4.2.5.3 Strings
AMQP 字符串是可變長度,由一個整數長度后跟零個或多個字節數據表示. AMQP定義了兩種原生字符串類型:
短字符串(Short strings),以8位無稱號整形長度后跟0個或多個字節數據存儲. 短字符串可攜帶最多255字節的UTF-8數據, 但不能包含二進制零字節.
長字符串(Long strings), 以32位無稱號整形長度后跟0個或多個字節數據存儲. 長字符串可包含任意數據.
4.2.5.4 時間戳(Timestamps)
時間戳是以精度為1秒的64位POSIX time_t 格式保存的.使用64伴可以避免31位和32位相關的time_t值概括問題(wraparound issues).
4.2.5.5 字段表
字段表是包含名稱-值對的長字符串. 名稱-值對編碼為:以短字符串定義名稱,字節定義值類型和值. 有效的表字段類型是原生整形,位,字符串,時間戳類型的擴展. 多字節整形字段通常是按網絡字節順序保存的.
指導方針:
字段名稱必須以字母開頭,其后可跟'$,'#',數字,下劃線,最大長度為128個字符.
server應該驗證字段名稱,如果收到了無效的字段名稱,它應該使用回復碼503(語法錯誤)來發出異常信號.
十進制值不用于支持浮點值,它是固定的業務值,如貨幣匯率和金額。其字節編碼代表了位置編號,其后跟著一個無符號的長整數.“十進制”是無符號的.
重復字段是非法的。對于一個包含重復字段的表,其行為是未定義的。
4.2.6 內容幀
某些特定的方法(Publish, Deliver, etc.) 會攜帶內容.請參考 "Functional Specifications" 來了解每種方法的說明,以及它們是否是攜帶內容的方法.
內容由1個或多個幀組成:
1. 只有一個內容頭幀能提供內容屬性.
2. 可選的, 可以有1個或多個內容體幀.
特定通道上的內容幀是嚴格有序的. 也就是說,它們可以和其它通道的幀混合,但同一個通道內兩個幀是不可能混合或重疊, 也不可能出現單個內容上的內容幀與相同通道上的方法幀相混合.
注意,任何非內容幀都會明確地標識內容的結束. 盡管可從內容頭中知道內容的大小,但也允許發送者在不關閉通道的情況下中止內容發送.
實現者指導方針:
收到不完整或錯誤格式內容的節點必須使用回復碼500(非希望幀)拋出一個連接異常. 這包括缺少內容頭,內容頭中錯誤的class IDs,缺少內容體幀等等.
4.2.6.1 內容頭
內容頭負載有下面的格式:

實現者指導方針:
class-id必須與方法幀class id匹配. 節點必須對無效的class-id使用501回復碼(幀錯誤)拋出一個連接異常.
weight字段未使用且必須是0.
body大小是一個64位值,它定義了內容體的總大小,也就是后面內容體幀的body大小的總和. 0表示無內容體幀.
property flags是位數組,它表示每個屬性的存在性. 位是從最高到最低進行排序的,位15代表第一個屬性.
property flags可指定多于16屬性.如果最后位(0)被設置了,這表明其后有進一步的屬性標志字段。根據需要,這里有許多屬性標志字段。
屬性值是特定類的AMQP數據字段.
位屬性僅由它們各自的屬性標志(0或1)表示,并且在屬性列表中不存在。
內容幀中的通道編碼不能為0.在內容幀中收到0通道編號的節點必須使用504回復碼(通道錯誤)來發出異常信號
4.2.6.2 內容體
內容體負載是是不透明的二進制塊,其后跟著一個結束幀字節:

內容體可以根據需要分成多個幀.幀負載的最大大小可在連接時,由兩端進行協商.
實現者指導方針:
節點必須要能將分成多個幀的內容體作為單一集合進行存儲處理,要么分成更小的幀重新傳輸,要么 連接成單個塊分發給應用程序.
4.2.7 心跳幀
心跳幀告訴收件人發件人仍然是活的. 在連接時,心跳幀的速率和時間都可以調整.
實現者指導方針:
心跳幀的通道編號必須為0. 收到無效心跳幀的節點需使用501回復碼(幀錯誤)來拋出異常.
如果節點不支持心跳,它必須在不發出錯誤或失敗信號的情況下丟棄心跳幀.
client收到Connection.Tune方法后,必須要開始發送心跳, 并在收到Connection.Open后,必須要開始監控.server在收到Connection.Tune-Ok后,需要開始發送和監控心跳.
節點應該盡最大努力按固定頻率來發送心跳. 心跳可在任何時候發送. 任何發送字節都可作為心跳的有效替代,因此當超過固定頻率還沒有發送非AMQP心跳時,必須發送心跳.如果節點在兩個心跳間隔或更長時間內,未探測到傳入的心跳,它可在不遵循Connection.Close/Close-Ok握手的情況下,關閉連接,并記錄錯誤信息.
心跳應該具有持續性,除非socket連接已經被關閉, 包括在Connection.Close/Close-Ok 握手期間或之后的時間.
4.3 通道復用
AMQP 允許節點創建多個獨立的控制線程.每個通道都可作為共享單個socket的虛擬連接:

實現者指導方針:
AMQP節點可支持多個通道.在連接協商期間,可定義最大通道數目,節點可協商這個數值為1.
每個節點都應該以公平的方式平衡所有打開通道的流量. 這種平衡可以每幀為基礎,也可以以每個通道上的總交通流量為基礎. 節點不應該允許一個非常繁忙的通道讓一個不太繁忙的通道餓死.
4.4 可見性保證
服務器必須確保客戶端對服務器狀態的觀察是一致的。
下面的示例說明了在這種情況下,客戶端的觀察方法:
Client 1 和 Client 2 連上了同一個虛擬主機
Client 1 聲明了一個隊列
Client 1 收到了Declare.Ok回復 (觀察”的一個例子)
Client 1 將其告知了Client 2
Client 2 對同一個隊列做了被動聲明
可見性必須保證Client 2能看到隊列(在沒有刪除的情況下)
4.5 通道關閉
當發生以下事件時,server會考慮通道已經關閉了:
1. 節點關閉了通道或其父連接使用了Close/Close-Ok握手.
2. 節點在通道或父連接上拋出了異常.
3.節點未使用 Close/Close-Ok握手關閉了父連接socket.
當服務器關閉通道時,通道上任何未應答的消息將標記為重新分發.
當服務器關閉連接時,它會刪除連接所擁有的自動刪除信息.
4.6 內容同步
在某些情況下,同步請求響應方法會對同一個信道上的異步內容傳遞產生影響,包括:
Basic.Consume 和 Basic.Cancel 方法, 這些會啟動和停止消息隊列中的消息流.
Basic.Recover 方法,它會要求服務器重新分發消息到通道.
Queue.Bind, Queue.Unbind, 和Queue.Purge 方法, 它會影響消息進入消息隊列.
實現者指導方針:
請求-響應效果在response方法之前必須不可見,但在之后必須可見.
4.7 內容排序保證
流經通道的方法順序是穩定的:方法按發送時的順序接收. 這是由AMQP使用的TCP/IP傳輸所保證的.
此外,服務器也會按一種穩定的方式來處理內容.尤其是,經過服務器中單個路徑的內容會保持順序.
對于設定了優先級并經過單個路徑內容,我們定義了一個內容處理路徑-由一個傳入通道,一個交換器,一個隊列和一個傳出通道組成.
實現者指導方針:
server必須保持流經單個內容處理路徑上的順序性,除非在Basic.Deliver或Basic.Get-Ok方法上設置了redelivered字段,可根據條件規則來設置字段.
4.8 錯誤處理
4.8.1 異常
使用標準的異常編程模型, AMQP不會發出成功信號,只在失敗時才發出信號. AMQP定義了兩種異常級別:
1. 通道異常.指那些關閉通道引起的錯誤.通道異常通常是因為軟錯誤引起的,這些錯誤并不影響應用程序的其它部分.
2. 連接異常. 這些關閉socket連接的異常通常是因為硬錯誤造成的,如程序錯誤,錯誤配置或其他需要干預的情況。
4.8.2 回復代碼格式
AMQP 回復代碼按照 IETF RFC 2821的回復代碼的嚴重程度和理論進行定義.
4.9 限制
AMQP規范為將來的AMQP擴展或同種線路級格式使用了如下限制:
每個連接上的通道數量: 16位通道數量.
協議類數量: 16位class id.
每個協議內的方法數量: 16位 method id.
AMQP規范對于數據做了如下限制:
短字符串的最大長度為: 255字節.
長字符串或字段表的最大長度: 32位大小.
幀負載的最大大小: 32位大小
內容的最大長度: 64位大小.
服務器或客戶端也可以對資源施加自己的限制,如并發連接的數量、每個通道的消費者數量、隊列的數量等。這些不影響互操作性,因此并沒有指定。
4.10 安全
4.10.1 目標和原則
為了防止緩沖區溢出,我們在所有地方都使用特定長度的緩沖區. 當讀取數據時,所有數據都可以使用允許的最大長度來進行驗證.無效的數據可以被明確地處理,通過關閉通道或連接。
4.10.2 拒絕服務攻擊
AMQP 通過回復碼并關閉通道或連接來處理錯誤.這避免了錯誤出現后的模糊狀態.在連接協商期間,服務器可假設特殊條件是因獲取訪問服務器的敵對嘗試所造成的.對于連接協商中的任何異常,一般處理是暫停該連接 (可能是一個線程)幾秒種時間,然后再關閉網絡連接. 這包括語法錯誤,過大數據,或認證失敗.服務器應該記錄所有這些異常標志或阻止客戶端挑起多個故障.