投遞狀態
發送消息時,將得到包含SendStatus
的SendResult
。首先,我們假設消息的isWaitStoreMsgOK
= true(默認是true)。如果不是,我們將總會得到SEND_OK,如果沒有拋出異常。下面是關于每個狀態的描述列表:
-
FLUSH_DISK_TIMEOUT
如果 Broker 設置
MessageStoreConfig
的FlushDiskType=SYNC_FLUSH
(默認是ASYNC_FLUSH
),并且代理沒有在MessageStoreConfig
的syncFlushTimeout(默認是5秒)時間內完成刷盤,您將獲得這個狀態。 -
FLUSH_SLAVE_TIMEOUT
如果 Broker 的角色是
SYNC_MASTER
(默認是ASYNC_MASTER
),并且 Slave Broker 沒有在MessageStoreConfig
的syncFlushTimeout(默認是5秒)時間內完成同步,您將得到這個狀態。 -
SLAVE_NOT_AVAILABLE
如果代理的角色是
SYNC_MASTER
(默認是ASYNC_MASTER),但是沒有配置 Slave Broker ,您將獲得這個狀態。 -
SEND_OK
SEND_OK 并不意味著它是可靠的。為了確保沒有信息會丟失,應啟用 SYNC_MASTER 或 SYNC_FLUSH
重復或者丟失消息
如果您得到FLUSH_DISK_TIMEOUT
、FLUSH_SLAVE_TIMEOUT
并且 Broker 恰好在此時意外宕機,您會發現你的消息丟失。此時,您有兩個選擇,一個是不管它,這可能導致這個消息丟失;另一個是重新發送消息,這可能會導致消息重復。我們經常建議重新發送,然后再消費時使用某個方法移除重復的消息。除非你覺得一些信息丟失并不重要。但是請記住,當您得到 SLAVE_NOT_AVAILABLE
狀態時,重新發送是沒有用的。如果出現這種情況,您應該保存場景并通知集群管理
超時
客戶端發送請求到 Broker ,并等待響應,但如果最大等待時間過去了,沒有返回響應,客戶端就會拋出一個RemotingTimeoutException
。默認的等待時間是3秒。您還可以使用 send(msg, timeout)
代替 send(msg)
來傳遞超時參數。注意,我們不建議等待時間過小,因為 Broker 需要一些時間來刷新磁盤或與 Slave 進行同步。而且,如果它超過 syncFlushTimeout,那么它的值可能不會有多大的影響,因為在超時之前,代理可能會以FLUSH_SLAVE_TIMEOUT
或FLUSH_SLAVE_TIMEOUT
返回響應。
消息大小
我們建議的消息的大小應該不超過 512 K。
異步發送
默認 send(msg)
將阻塞直到返回的響應。所以如果你關心的是性能,我們建議你使用 send(msg, callback)
,這將會以異步方式發送。
生產者組
正常情況下,生產者組沒有影響。但如果你開啟了事物,你應該注意它。默認情況下,您只能在同一個JVM中只創建同一個生產者組,這通常是足夠的。
線程安全
生產者是線程安全的,您可以在業務解決方案中使用它。
性能
如果您希望在一個JVM中有多個生產者進行大數據處理,我們建議:
- 與一些生產者一起使用異步發送(3 ~ 5就足夠了)
- 為每個生產者setInstanceName