RocketMQ的最佳實踐

對RocketMQ使用者的一些有用建議。數據庫

代理角色

代理角色有:異步主節點,同步主節點和從節點。 若是你不能容忍消息丟失,咱們建議你部署同步主機並在其上附加從屬服務器。若是您對丟失能夠容忍,但但願代理始終可用,則能夠將ASYNC_MASTER和SLAVE一塊兒部署,若是你只想簡單一點,你可能只須要一個沒有從節點的異步主機。編程

刷新磁盤類型

建議使用異步刷新,由於同步刷新時很是昂貴的,會形成太多的新能損失。若是你想要可靠性,咱們建議您使用同步主機和叢機。安全

生產者的最佳實踐

發送狀態

當發送一條消息,你將會獲得一個發送狀態和一個發送結果,首先咱們建設消息的iswaitstoremsgok=true(默認爲true), 若是沒有異常,咱們將始終收到"OK", 如下是每一個狀態描述列表:bash

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
複製代碼
相關文章
相關標籤/搜索