天天看點

RabbitMQ學習(十六):消息确認之消費者确認模式 I說明概述

說明

通過上篇博文《RabbitMQ學習(十五):消極确認》我們初步了解了消費者對消息确認的相關内容,通過消極确認,消費者可以拒絕一個消息。本篇博文,我将繼續翻譯學習官方文檔中關于消息确認的相關内容。由于原文檔太長,本篇博文隻翻譯消費者确認的部分内容。通過本篇博文,我們将了解到消息确認機制的意義,消息确認的不同模式,消息确認對吞吐量的影響等内容。

概述

消息者确認機制和發送者确認機制對資料安全十分重要,本文将圍繞以下幾個要點展開:

  • 為什麼要有确認機制?
  • 手動确認和自動确認的差別
  • 進行消息确認的API的不同用法,實作不同的目的 – 批量确認 和 重新入隊
  • 連接配接丢失或通道關閉時,消息安全性的保證 (自動重新入隊)
  • 影響吞吐量的通道最大累積未确認消息數量的設定

消息确認的必要性

使用消息中間件(如 RabbitMQ)的系統被定義為分布式系統。因為中間件使用的協定方法在發送消息後不能保證消息已經被接收或者已經被成功處理,是以發送者和消費者需要對消息發送和處理進行确認的機制。RabbitMQ支援的一些協定中提供了類似的功能。

AMQP 0-9-1協定支援消息者對伺服器進行消息傳輸确認,同時該協定有一個被稱為發送者确認的擴充,伺服器用來對發送者進行确認。這兩種方式都基于相同的思想,受到了TCP的啟發影響。

發送者到伺服器,伺服器到消息者,這中間的消息傳輸的可靠性是必須的。換句話說,它們對資料的安全性是必須的,資料安全對應用程式和RabbitMQ一樣重要。

消息者傳輸确認

當伺服器發送一個消息到消費者,它需要知道什麼時候消息可以被認為已經成功發送。這個時機有系統決定,它主要是一個應用程式的選擇。在AMQP 0-9-1協定中,當一個消費者被注冊後,使用basic.consumer方法或者消息者根據需要使用basic.get方法來消費消息。

傳輸标簽(Delivery Tags)

在我們學習其他内容之前,我們必須清楚伺服器如何确認每次的傳輸(确認消息表明屬于哪個傳輸)。當消費者被注冊後,伺服器将使用basic.deliver方法将消息推送給消費者。這個方法攜帶了一個傳輸标簽,該标簽具有唯一性,表明了在該通道的哪次傳輸。是以,傳輸标簽隻能作用于每個通道。

傳輸标簽是一個單調遞增的正整數,嚴格意義上由用戶端庫提供。用戶端庫方法在确認時,将一個傳輸标簽作為參數進行傳遞。

傳輸标簽作用于每個通道,是以傳輸的确認通道必須與接收的通道一緻。當在不同的通道上進行确認時,将引起"unknown delivery tag"協定異常,并且導緻通道關閉。

消費者确認模式和資料安全

當伺服器發送消息到消費者時,它必須決定消息是否可以被以為已經被消息處理(或者至少已經被接收到)。由于多種因素(用戶端連接配接,消費者程式等)會失敗崩潰,是以這個決定關乎着資料安全問題。消息傳輸協定經常提供一個确認機制,它允許消費者進行傳輸确認。這個機制是否被使用在消費者訂閱時決定。

依賴于确認機制的使用,RabbitMQ可以認為一個消息在被發送後或者是接收到一個明确的用戶端确認消息後,該消息已經被成功發送。手動發送确認消息時,可以使用以下協定方法發送積極确認或消極确認消息:

  • basic.ack 被用來發送積極确認
  • basic.nack 被用來發送消極确認 (這個發送時RabbitMQ對AMQP 0-9-1協定的一個擴充)
  • basic.reject 被用來發送消極确認,但與basic.nack方法有個限制

關于消極确認的兩個方法,詳見 RabbitMQ學習(十五):消極确認

積極确認消息告訴伺服器消息已被發送可以丢棄(删除)。使用basic.reject方法發送的消極确認消息具有同樣的效果,但是它們之間最主要的差別是:積極确認消息假定消息已經被成功處理,然而消極确認消息表明消息沒有被處理單仍應該被删除。

在自動消息确認模式中,一個消息在被發送後就立即被認為已經成功傳遞。該模式可以實作更高的吞吐量,但犧牲了傳輸和消費者處應該理的安全性。這個模式經常被認為是“發後即忘”。不像手動确認模式,如果消費者的TCP連接配接或者通道在成功傳輸前被關閉,伺服器發送的消息将會丢失。是以,自動消息确認機制應該被任務時不安全的,并且不适用于所有的場景。

另外,當使用自動消息确認模式時,消息者可能會過載(記憶體溢出)。手動确認模式設定了通道的prefetch值來限制在該通道中未被确認(正在被處理)的消息的數量。然而,在自動确認模式中,沒有類似的限制。是以,消費者可能會因為消息的傳輸速率過快,造成消息在記憶體中積壓使得記憶體耗盡,導緻記憶體溢出或者被系統終止程式。在一些用戶端中,使用了TCP來緩解壓力(停止從socket緩沖區讀取消息,直到積壓的消息數量降低到臨界值以下)。是以,自動消息确認模式僅推薦用于處理消息速度快并且穩定的消費者。