1. 交易完成

當使用 Apache ActiveMQ Artemis 提交或回滾交易時,提交或回滾的請求會被傳送到伺服器,並且用戶端上的呼叫會被阻塞,直到收到來自伺服器的回應,表示提交或回滾已執行完成。

當伺服器接收到提交或回滾時,它會將其提交到日誌中,並且根據參數 journal-sync-transactional 的值,伺服器會確保提交或回滾在將回應發送回用戶端之前被持久儲存到儲存裝置中。如果此參數的值為 false,則提交或回滾可能在將回應發送給用戶端之後的一段時間內才實際被持久儲存到儲存裝置中。在伺服器故障的情況下,這可能意味著提交或回滾永遠不會被持久儲存到儲存裝置中。此參數的預設值為 true,因此用戶端可以確定,當提交或回滾的呼叫返回時,所有交易的提交或回滾都已持久儲存到儲存裝置中。

將此參數設定為 false 可以在犧牲一些交易持久性的情況下提高效能。

此參數在 broker.xml 中設定。

2. 非交易訊息傳送

如果您使用非交易的會話將訊息傳送到伺服器,可以將 Apache ActiveMQ Artemis 設定為阻塞傳送呼叫,直到訊息確實已到達伺服器,並且已將回應發送回用戶端。可以針對持久訊息和非持久訊息分別進行設定,並由以下兩個 URL 參數確定:

blockOnDurableSend

如果此參數設定為 true,則在非交易會話中,所有針對持久訊息的傳送呼叫都會被阻塞,直到訊息已到達伺服器,並且已將回應發送回來。預設值為 true

blockOnNonDurableSend

如果此參數設定為 true,則在非交易會話中,所有針對非持久訊息的傳送呼叫都會被阻塞,直到訊息已到達伺服器,並且已將回應發送回來。預設值為 false

將傳送阻塞設定為 true 會降低效能,因為每次傳送都需要網路往返才能執行下一次傳送。這表示傳送訊息的效能將受到您網路的網路往返時間 (RTT) 限制,而不是網路頻寬的限制。為了獲得更好的效能,我們建議在交易中批量處理許多訊息傳送,因為使用交易會話時,只有提交/回滾會阻塞,而不是每次傳送,或者使用 Apache ActiveMQ Artemis 的進階非同步傳送確認功能,如非同步傳送確認中所述。

當伺服器收到來自非交易會話的訊息,並且該訊息是持久性的,並且該訊息被路由到至少一個持久佇列時,伺服器會將該訊息持久儲存到永久儲存裝置中。如果日誌參數 journal-sync-non-transactional 設定為 true,則伺服器在訊息被持久儲存並且伺服器保證資料已被持久儲存到磁碟之前,不會將回應發送回用戶端。此參數的預設值為 true

3. 非交易確認

如果您在用戶端使用非交易會話確認訊息的傳遞,可以將 Apache ActiveMQ Artemis 設定為阻塞確認呼叫,直到確認確實已到達伺服器,並且已將回應發送回用戶端。此設定由參數 BlockOnAcknowledge 進行。如果此參數設定為 true,則在非交易會話中,所有確認呼叫都會被阻塞,直到確認已到達伺服器,並且已將回應發送回來。如果您想要實作嚴格的「最多一次」傳遞策略,您可能會想要將此設定為 true。預設值為 false

4. 非同步傳送確認

如果您使用非交易會話,但想要保證傳送到伺服器的每個訊息都已到達,那麼如非交易訊息傳送保證中所述,您可以將 Apache ActiveMQ Artemis 設定為阻塞傳送呼叫,直到伺服器已接收到訊息、持久儲存訊息並發送回回應。這效果不錯,但效能損失嚴重 – 每次傳送呼叫都需要至少阻塞一個網路往返時間 (RTT) – 因此傳送效能受到網路延遲的限制,而不是受限於網路頻寬。

讓我們做一些簡單的數學來看看這有多嚴重。我們將考慮一個標準的 1Gib 乙太網路,其伺服器與用戶端之間的網路往返時間為 0.25 毫秒。

在 RTT 為 0.25 毫秒的情況下,如果用戶端阻塞每次訊息傳送,則最多每秒可傳送 1000 / 0.25 = 4000 則訊息。

如果每則訊息小於 1500 位元組,並且網路使用標準的 1500 位元組 MTU(最大傳輸單元)大小,則在不阻塞的情況下傳送訊息,1GiB 網路的理論上限為 (1024 * 1024 * 1024 / 8) / 1500 = 每秒 89478 則訊息!這些數字並非精確的科學,但您顯然可以看到受限於網路 RTT 會對效能產生嚴重影響。

為了補救這一點,Apache ActiveMQ Artemis 提供了一項稱為非同步傳送確認的進階新功能。使用此功能,可以將 Apache ActiveMQ Artemis 設定為單向傳送訊息而不阻塞,並在單獨的資料流中非同步取得來自伺服器的訊息接收確認。透過將傳送與傳送確認分離,系統不受限於網路 RTT,而是受限於網路頻寬。因此,可以實現比使用阻塞方法更高的輸送量,同時絕對保證訊息已成功到達伺服器。

傳送確認的視窗大小由連線工廠或用戶端會話工廠上的 confirmation-window-size 參數確定。請參閱用戶端故障轉移,以取得更多資訊。

若要使用核心 API 使用此功能,請實作介面 org.apache.activemq.artemis.api.core.client.SendAcknowledgementHandler 並在您的 ClientSession 上設定一個處理常式實例。

然後,您只需使用您的 ClientSession 照常傳送訊息,當訊息到達伺服器時,伺服器會非同步傳回傳送確認,稍後 Apache ActiveMQ Artemis 會透過呼叫您處理常式的 sendAcknowledged(ClientMessage message) 方法來通知您用戶端,傳入已傳送訊息的參考。

若要啟用非同步傳送確認,您必須確保 confirmationWindowSize 設定為正整數值,例如 10MiB。

請參閱範例章節以取得完整的工作範例。