支援 IO 串流
如果能為 ActiveMQ Classic 提供超棒的串流檔案支援,允許傳輸任意大小的檔案,那就太棒了。基本概念是將串流分割成多個訊息,然後透過 JMS 發送/接收。
有幾個問題需要考慮…
使用案例
- 多個生產者寫入,但只有 1 個消費者。理想情況下,每個消費者應一次完整處理 1 個串流(IO 串流通常是阻塞式 IO,因此客戶端執行緒在讀取 1 個串流時,無法處理其他串流)。
- 如果消費者透過 10GB 的檔案接收了 1GB,然後死機了,我們需要將訊息重新傳遞給另一個消費者。
目標
我們的目標應該是
- 讓每個消費者在嘗試處理另一個串流之前,一次處理一個串流。
可能的失敗情況
- 消費者可能在讀取串流的過程中死機。復原選項
- 捨棄串流的剩餘部分
- 重新開始將串流傳遞給下一個消費者
- 在失敗點繼續將串流傳遞給下一個消費者。
- 生產者可能在寫入串流的過程中死機。我們可能需要偵測到他的失敗。我們可以
- 在交易中發送串流。在 Broker 完全接收到串流之前,不會將串流發送給消費者。缺點:消費者在能夠接收訊息之前會有較高的延遲。
- 消費者逾時:如果訊息沒有及時收到,消費者會假設生產者已經死機。(如果他沒有死機怎麼辦??)
- 消費者可能開始接收串流的中間部分。可能會發生的情況
- 如果另一個消費者假設 Broker 已經死機(但它實際上並沒有)。
- 如果非串流消費者意外移除了訊息,或者訊息由於消費者回滾而被發送到 DLQ。
實作問題
- 我們可以使用訊息群組來確保同一個消費者處理給定串流的所有訊息 - 但不幸的是,訊息群組無法防止消費者一次超載多個訊息群組 - 也許這是我們可以新增的新功能?
- 避免 Broker 耗盡 RAM - 因此,如果唯一的消費者正在處理不同的串流,則將資料假脫機到磁碟(或限制生產者)。
- 如果訊息使用交易發送,可能需要對我們進行交易管理和訊息日誌的方式進行重大變更。目前,正在進行交易中的所有訊息都保存在記憶體中,直到它提交(同步回呼保留著訊息)。日誌目前將所有交易訊息保存在其日誌 + 記憶體中,直到提交,它現在不允許日誌將屬於正在進行交易的訊息翻轉。
- 鑑於必須一次處理整個串流,我們只能 ACK 整個訊息串流 - 因此我們需要停用預先提取嗎?
- 不需要停用預先提取,因為消費者會發送一種特殊的 ACK,它只會暫時擴大預先提取視窗。