RocketMQ的最佳實踐

Charse發表於2019-05-04

代理的最佳實踐

對使用者的一些有用方法.

代理角色

代理角色有:非同步主節點,同步主節點和從節點. 如果你不能容忍訊息丟失,我們建議你部署同步主機並在其上附加從屬伺服器.如果您對丟失可以容忍,但希望代理始終可用,則可以將ASYNC_MASTER和SLAVE一起部署,如果你只想簡單一點,你可能只需要一個沒有從節點的非同步主機.

重新整理磁碟型別

建議使用非同步重新整理,因為同步重新整理時非常昂貴的,會造成太多的新能損失.如果你想要可靠性,我們建議您使用同步主機和叢機.

生產者的最佳實踐

對使用者的一些有用的方法.

傳送狀態

當傳送一條訊息,你將會得到一個傳送狀態和一個傳送結果,首先我們建設訊息的iswaitstoremsgok=true(預設為true), 如果沒有異常,我們將始終收到"OK", 以下是每個狀態描述列表:

FLUSH_DISK_TIMEOUT:重新整理超時時間

如果代理設定了MessageStoreConfig的FlushDiskType=SYNC_FLUSH(預設是ASYNC_FLUSH),並且代理未在messagestoreconfig的syncflushtimeout預設為5秒)內完成磁碟重新整理,則將獲得此狀態.

FLUSH_SLAVE_TIMEOUT:重新整理從節點超時

如果代理的角色時同步主機(預設非同步主機),如果從機代理沒有在MessageStoreConfig的syncFlushTimeout(預設時5秒)時間內非同步重新整理,則將獲得此狀態.

SLAVE_NOT_AVAILABLE:從機不可用

如果代理的角色是同步主代理(預設時非同步主代理), 但是沒有配置從屬代理,則將會獲得這個狀態.

SEND_OK:傳送成功

傳送"確定"並不意味著它是可靠的,為確保不會丟失任何訊息,應該啟用同步主機或同步重新整理.

Duplication or Missing: 重複或丟失

如果您得到了flush-disk-timeout,flush-slave-timeout,並且代理在此時正好關閉,那麼您可以發現您的訊息丟失了.這個時候你有兩種選擇,一個是讓它離開,這可能導致這個訊息丟失,另一個時重新傳送訊息,這個可能會導致訊息重複.通常,我們建議重新傳送並在使用時找到處理重複刪除的方法.除非你覺得當一些資訊丟失時沒有關係.但是請記住,當沒有從屬主機時,重新傳送是無用的,如果發生這種情況,寧應該保留場景並警告叢集管理器.

超時

客戶端向代理髮送請求,並等待響應,但是如果最大等待事件已經過去,並且沒有返回響應,則客戶端將丟擲一個RemotingTimeoutException.預設等待時間時3秒,你可以通過使用send(msg, timeout) 方法來設定超時時間來代替send(msg).注意,我們不建議等待時間設定得太短.因為代理需要一些時間來重新整理磁碟或與從屬伺服器同步.

另外,如果該值超過了syncflushtimeout太多,則效果可能很小,因為代理可能會在超時之前返回FLUSH_SLAVE_TIME 或 FLUSH_SLAVE_TIMEOU

訊息體大小

我們建議訊息提的大小時不超過512K.

非同步傳送(Async Sending)

預設的send(msg方法在接收到返回響應訊息之前,將會被一直阻塞,因此,如果寧關心效能,我們建議您使用send(msg, callback), 它將以非同步的方式進行工作.

生產組(Producer Group)

通常,生產者組是沒有影響的.但是如果你加入了一個事物,你就應該注意,預設情況下,在同一個JVM中只能建立一個具有相同生產組的生產這,這通常已經足夠了.

執行緒安全

生產者是執行緒安全的.您可以業務解決方案中使用它.

效能

如果你希望在一個JVM中有多個生產者進行大資料處理.我們建議:

  • 使用幾個生產者非同步傳送(3-5個就足夠了)
  • 為每個生產者設定例項名稱

消費的最佳實踐

為使用者提供一些有用的提示

消費組和訂閱

首先,你需要注意的是,不用的消費組可以獨立的消費同一個主題,並且每個消費組都有自己的消費補償.請確保同一組中的每個消費者訂閱相同的主題.

訊息監聽器

Orderly

消費者將鎖定每個訊息佇列,以確保按順序逐個消費它.這個將導致效能損失,但當你關係訊息的順序時,它是有用的.不建議丟擲異常,你可以返回ConsumeOrderlyStatus.SUSPEND_CURRENT_QUEUE_A_MOMENT.

Concurrently

顧名思義,使用者將併發消費.建議使用它以獲得良好的效能,不建議丟擲異常,你可以使用ConsumeConcurrentlyStatus.RECONSUME_LATER 來進行替代.

Consume Status

對MessageListenerConcurrently來說,你可以返回RECONSUME_LATER告訴消費者你現在不能馬上消費它,想稍等一會兒再消費它,然後你可以繼續消費其他訊息,對MessageListenerOrderly來說,因為你關心的是順序,你不能跳過某一條訊息,但是你可以返回SUSPEND_CURRENT_QUEUE_A_MOMENT(暫停當前佇列)來告訴消費者等待一會兒

Blocking

不建議阻塞監聽器,因為它會阻塞執行緒池,最終可能會導致消費程式的停止.

執行緒數量

消費者使用ThreadPoolExecutor來處理內部消費,因此您可以通過setConsumeThreadMin或者setConsumeThreadMax來改變最大消費執行緒數和最大消費執行緒數.

從哪裡開始消費

當一個新的消費組建立時,它將需要決定是否需要消費已經存在與代理中的歷史訊息.

CONSUME_FROM_LAST_OFFSET: 這個配置將會忽略歷史訊息,並消費之後產生的任何內容.

CONSUME_FROM_FIRST_OFFSET: 這個配置將會消費代理中存在的所有訊息.

CONSUME_FROM_TIMESTAMP: 這個配置將消費指定時間戳之後再生成訊息.

重複

許多情況可能導致重複,例如:

  • 生產者重複傳送(例如: 在FLUSH_SLAVE_TIMEOUT的情況下)
  • 消費者關閉,某些補償機制未及時更新到代理

因此,如果應用程式不能容忍重複,你可能需要做一些外部工作來處理這一問題,例如: 通過檢查資料庫的主鍵.

名稱服務的最佳實踐

在ApacheRocketMQ中,名稱伺服器被設計為協調分散式系統的每個元件,協調主要通過管理主題路由資訊來實現.

管理主要由兩部分構成:

  • 代理定期更新儲存在每個名稱伺服器中的後設資料
  • 名稱伺服器為客戶端服務,包括生產者,消費者和命令列客戶機提供最新的路由資訊

因此,在啟動代理和客戶端之前,我們需要告訴他們如果通過名稱伺服器提供名稱伺服器地址列表來訪問名稱伺服器.在Apache RocketMQ中可以通過四種方式實現.

程式設計的方式

Java配置項

名稱伺服器地址列表可以通過在啟動之前指定後繼Java選項rocketmq.namesrv.addr來提供給應用程式.

環境變數

HTTP端

優先順序

首先介紹的方法優於後面介紹的方法:

Programmatic Way > Java Options > Environment Variable > HTTP Endpoint
複製程式碼

相關文章