上一章:什麼是消息隊列Rocket MQ| 《Rocket MQ 使用排查指南》第一章>>>
下一章:消費問題排查 | 《Rocket MQ 使用排查指南》第三章>>>
也可以PC端點擊https://developer.aliyun.com/topic/download?id=820下載
發送問題排查
客戶端發送性能問題
發送消息耗時久
【問題描述】:
通過消息軌跡查詢到,MQ 消息發送的耗時達到秒級之上。
【排查步驟】:
- 首先確認該現象是偶發還是頻繁出現。
- 其次確認是部分機器發送有問題還是大量機器發送都存在此現象。
- 接著檢查是少量的 topic 發送有此現象還是大部分機器如此。
- 確認您的應用機器的外網帶寬。
- 檢查發送消息的時間佔比。
【問題原因】:
-
如果是偶發現象,檢查現象存在期間您發送端的 TPS、網絡狀態以及出口 ip 的連接情況、確認期間應用是否有 Full GC(Full GC 會造成網絡延遲 ),可 結合 ons.log 來綜合分析。
- 如果部分機器有問題,那麼登錄該機器,查看網絡流量以及 tps。
- 若客戶端帶寬過小,可建議升級帶寬。
- 如果頻繁現象,建議收集好信息反饋給技術支持人員,技術支持人員需要查 看下後端的 topic 集群是否有問題。
延時消息發送性能問題
【問題描述】: 業務大量使用發送延時消息,可以指定延時 15 天之後再投遞消費嗎?
看開源的代碼是單線程去處理這些延遲消息的隊列, 如果有大量消息在隊列中, 性能上也是沒有問題的嘛。
【問題回答】:
延時消息我們會先存 DB,在指定的時間掃描 DB,再將消息存儲到 broker 上, 投遞給消費端。並且這個存 DB 和掃碼 DB 都是後端完成的。
也是因為這個存儲 DB 和掃碼的 DB 的損耗,所以我們的定時消息性能是沒有普 通消息高的。
普通消息是直接發送存儲到 broker 上的。延時消息就是多了兩層的消 耗的。 普通消息和延遲消息是不一樣的,這二者不存在轉換的關係的。
為什麼用普通消息的 topic 發送延遲消息也可以成功
【問題描述】:
topic 主題類型分為好幾種,但是測試發現無論使用普通消息類型還是延時定時 消息類型都一樣沒問什麼區別。
比如創建的普通消息類型 topic 但是發送延時消息也是可以使用的。總結來 說 :topic 消息類型有作用嗎。
【問題回答】:
往普通消息類型 topic 當中發送延時消息,是可以成功,但是不保證一定成功, 也不保證相應的性能。
但是如果您嚴格按照消息類型創建對應的 topic,並且發送相應類型的消息,性 能是會得到保障的。
客戶端發送常見異常報錯
啟動發送端時報錯 No route info of this topic
【問題描述】:
具體報錯異常如圖所示。
【排查思路】:
- 確認您在 MQ 控制檯 已創建 topic ,確認 topic 拼寫及對應,控制檯查詢比 對 topic。
- 檢查您代碼的接入點配置,是否是 MQ 控制檯上的接入點配置。
- 確認 NameServer 可以連接,telnet 接入點 + 端口,看是否能 telnet 通。
- 確認 NameServer 可用,curl 接入點,將獲得的地址和端口號也 telnet 下, 確認通暢。
-
確認 topic 權限可用,檢查您代碼中配置的 AK、SK 所屬的賬號是否擁有此 topic 的發佈訂閱權限發送或消費權限異常。
- 看是否發送消息的實例和發送端是在同一個 region 下的(如果是走的公網, 那麼就可以隨便在任何可以接入公網的機器上發送消息)。
阿里雲生產環境中消息隊列 For RocketMQ 除了公網 region 之外,其他 region不允許在本地使用,必須在對應區域的 ECS 機器上部署使用。
服務端限流 system|broker busy
【問題描述】:
在 ons.log 日 志 當 中 出 現 system busy, start flow control for a while 或 者broker busy, start flow control for a while 等異常信息。
【問題原因】:
- 共享集群,當時 broker 壓力大,會出現這個問題。
- broker 出現了網絡,磁盤,IO 等抖動時,會出現這個問題。
【排查步驟】:
- 首先看下是短暫偶爾抖動還是持續,持續多長時間?
- 如果是偶爾抖動,是系統升級或 broker 壓力大 , 或者抖動異常 , 但是 sdk 有 重試策略 , 會重試到其它的 broker,不影響消息的發送。
- 如果是長時間持續出現這種情況 , 那麼需要收集一下信息:uid/ 實例 id/ 地域 /topic 等給到技術支持人員,技術人員需要核實下後端集群狀態是否正常。
- 報錯建議您在自己的業務代碼層面 try...catch 進行重試。
1.8.4 版本的 skd 會自定進行 brokerbusy 的重試【不一定保證重試到其他的broker 一定是成功的】。
發送端出現發送超時異常
【問題描述】:
在ons.log日誌中出現RemotingConnectException: connect to <118.190.213.56:80>failed 或者 RemotingTimeoutException 等異常信息。
【排查步驟】:
- 首先可以確認該時間段內是否屬於服務升級時間段內 ( 可以看官網公告 ) 這 是 MQ 服務升級過程中 , 會出現短暫的網絡閃斷 , 但是我們的 mq 服務是集 群部署的 , 一臺網絡的閃斷是不會影響消息的。
- 在自己的應用服務器上執行 telnet brokerip port,確認服務端的端口是否 通暢。
- 執行 ping brokerip , 查看網絡是否延遲。同時檢查網絡監控指標,觀察在問 題時間點流量是否有下降的情況。如果 ping 或者 telnet 不通,需要檢查下 服務器的防火牆,網絡設置等。
- 檢查應用的網絡帶寬情況,是否打滿。
- 可執行 jstack -l 進程號 > 文件名 .dump 來分析堆棧信息,判斷當時應用系 統有沒有 Full GC 現象 (Full GC 會造成一定的網絡延遲 )。
- 確認下使用的 sdk,如果是較低的 javasdk 版本,建議升級 sdk 版本到 1.8.4。這個版本里容災策略較之前版本優化了許多內容。 同時建議客戶端做一下補償機制 ,可以 try…catch 一下異常,做下消息的重試。
啟動發送端連接異常
【問題描述】:
啟動消費端的時候,報錯連接,異常如下:
com.aliyun.openservices.ons.api.exception.ONSClientException: Can not find name server with
onsAddr http://**.mqrest.cn-hangzhou.aliyuncs.com
See http://docs.aliyun.com/cn#/pub/ons/faq/exceptions&namesrv_not_exist for further details.
at com.aliyun.openservices.ons.api.impl.rocketmq.ONSClientAbstract.fetchNameServerAddr(ONSClientAbstract.java:131)
at com.aliyun.openservices.ons.api.impl.rocketmq.ONSClientAbstract.(ONSClientAbstract.
java:84)
at com.aliyun.openservices.ons.api.impl.rocketmq.ProducerImpl.(ProducerImpl.java:35)
at com.aliyun.openservices.ons.api.impl.ONSFactoryImpl.createProducer(ONSFactoryImpl.
java:30)
at com.aliyun.openservices.ons.api.ONSFactory.createProducer(ONSFactory.java:89)
【排查方向】:
看報錯的異常是和接入點有關的,報錯是接入點不存在,需要和核實一下代碼當 中填入的接入點信息。
【問題原因】:
代碼當中使用的是杭州地域的 http 協議的公網接入點。
但是使用的是 tcp 協議的 sdk,代碼配置卻是 http 的接入點。
開源 python 發送端發送報錯
【問題描述】:
使用開源 python 的 tcp 官方提供的 demo,發送報錯。
【排查步驟】:
到 {home}/logs/rocketmqlogs 路徑下查看 mq 的日誌。
從日誌當中看到有連接報錯。
根據報錯懷疑是接入點接入點接入的有問題
【問題原因】:
代碼當中填入的是 http 的接入點,但是使用的是 tcp 的 sdk,應該使用控制檯提供的 tcp 的接入點。
需要注意的是,使用什麼連接類型的 sdk,就一定要對應使用控制檯提供的對應連接類型的接入點,如果使用錯誤,那麼代碼將不會運行成功。
Php 的 http 接入方式發送消息失敗
【問題描述】:
使用 php 的 http 接入方式,發送消息報錯,導致消息發送失敗。
報錯如圖。
【問題回答】:
internal error 一般是後端記錄有類似於網絡抖動的報錯異常。
遇到此類錯誤,需要將實例 id/ 地域 /topic/sdk 語言版本等信息收集反饋給到技術人員進行後端服務器核實。
發 送 消 息 報 錯 NumberFormatException: For inputstring: "//XXX"
【問題描述】:
啟動發送端,發送消息報錯 NumberFormatException: For input string: "//XXX。
【問題原因】:
出現這種問題肯定是 sdk 版本過低的原因,底層調用的 MQ 版本與 pom 裡配置 的 ons-sdk 版本不一致。
【解決方案】:
● 採用 mvn dependency:tree 分析依賴樹之間的關係。
● 如果是打出去的是 jar 包,將生成的 jar 解壓,然後在 lib 目錄下確認下 ons 的 版本是否正確,如下圖所示:
發送消息報錯權限異常
【問題描述】:
發送消息失敗,報錯:AuthenticationException 或者是
【問題原因】:
代碼中配置的 AK、SK 所歸屬的賬號,與創建 Topic 或者是 GID 的賬號並不匹 配,導致權限錯誤。
【解決辦法】:
- 檢查代碼當中配置的 ak 是否有調用 topic 發送消息的權限。
- 核實下 sdk 的版本,如果是平時發送消息都是正常,偶爾會出現這種異常 報錯信息。可以看下 sdk 版本是否是 1.7.9 版本的。如果是,建議升級 sdk。1.7.9 版本的 sdk 在鑑權的時候,的確會容易出現鑑權失敗的問題, 此版本在健全上有一些 bug。
- 檢查下代碼當中的接入點是否配置正確,可以 debug 看下,取到的接入點是 否和控制檯提供的接入點完全一致。
- 檢查下代碼當中配置的 topic 是否與控制檯創建的 topic 完全一致。
- 如果以上確認過都沒有問題,需要收集實例 id/ 地域 /topic/sdk 版本等信息 給到技術人員進行後端服務器狀態核實。
發送消息時日誌報錯
【問題描述】:
發送消息的時候,日誌記錄有報錯
com.aliyun.openservices.shade.com.alibaba.rocketmq.client.exception.MQBrokerException:
CODE: 1 DESC: [REJECTREQUEST]Broker in slave mode
【問題原因】:
這個報錯是因為優化後端集群節點的時候導致的報錯。對使用是沒有影響的哈, 只是日誌會有異常記錄下來。
也可以再觀察下,如果是持續大量報錯,並且消息會發送失敗,需要提供實例 id/ 地域 /topic 等信息給到技術人員進行查看。 消息體太大導致發送失敗
【問題描述】:
發送消息的時候報錯:
CODE:13 the message is illegal, maybe msg body or properties length not matched. msg bodylength limit 128k, msg properties length limit 32k. 此異常為消息屬性 properties 太大。 CODE:13 the message body size over max value, MAX:4194304。 此異常信息為消息 body 太大
【解決方案】:
- 消息體大小最大為 4MB, 一般建議發送的消息體在 4kb 之內 ( 性能最佳 )。
- 消息屬性最大為 32kb,一般建議發送的消息屬性在 1kb 之內 ( 性能最佳 )。
- 4MB 這個上限值不能修改,這個會影響全局性能。如果消息體的確很大,建 議側優化消息體的內容,避免發送大消息或者帶有鏈接地址的消息,或者可 以縮短或者分兩條發送。
應用部署在 edas 當中發送消息失敗
【問題描述】:
mq 的應用部署在 edas 當中,但是發送消息失敗。
【問題原因】:
通過發送報錯日誌看到 是 ons-client-1.7.1-EagleEye.jar 報錯, ons-client 的版本比較低,需要升級 ons-sdk 1.8.0-EagleEye 插件。
【解決方案】:
到 edas 控制檯點擊運行時環境升降級,將 edas 的容器版本升級到 3.5.3 及其以上,3.5.3 版本及其以上版本升級了 on-client 插件的版本。
發送時報錯 fetch name server address exception
【問題描述】:
發送消息的時候日誌出現 fetch name server address exception 異常信息。
【問題原因】:
根據代碼配置中的 ONSAddr 這個地址來獲取 NAMESRV_ADDR 時失敗了。
【排查步驟】:
- 檢查代碼配置,看配置的 ONSAddr 是否和控制檯上的一致,有可能配置錯了,將 NAMESRV_ADDR 當成了 ONSAddr,進行了如下圖配置。
- nslookup 接入點的域名看下。檢查 dns 是否正確。正確情況下,會獲取到綁定。
這個域名的 ip,在 ping 下 ip 是否是通的
nslookup onsaddr-internet.aliyun.com
發送消息報錯 not set any response code
【問題描述】:
發送延遲消息報錯。
【問題原因】:
設置的 message properties 中某個屬性的值過長,造成發送失敗。 【排查過程】:
- 查詢問題節點的消息,mq 控制檯對應的接口是 ConsoleMessageGetByPagedTopic,openApi 對應的接口是 OnsMessagePageQueryByTopic。
- 登錄 mq 控制檯,打開瀏覽者開發工具(win os: F12 mac os: command+ F12),找到如下圖所示的接口,查看返回的 response. 將其進行 json 化, 查看 properties 裡是否存在長度比較長的屬性值。
- openApi 裡 可 查 看 MsgFoundList>>OnsRestMessageDo>>PropertyList>>MessageProperty 裡的屬性是否有比較長的值。
發送消息 get user info by accesskey from ALIYUN failed.異常
【問題描述】:
發送消息的時候日誌報錯:
com.aliyun.openservices.ons.api.impl.authority.exception.AuthenticationException: get user info by accesskey from ALIYUN failed.
異常如圖
【問題原因】:
此問題不是權限報錯,而是 AK 出現了問題,去 ak 中心根據 ak 獲取子用戶信息出錯了,可以重新換個 ak 試試。
啟動發送者時報錯 UnknownHostException
【問題描述】:
啟動消息隊列 RocketMQ 版的客戶端時提示異常 UnknownHostException信息。
【問題原因】:
導致此問題的主要原因是客戶端無法獲取系統的主機名(Hostname)或者系統的 IP 地址。
【解決方案】:
請參考以下步驟進行排查:
- 登錄客戶端所在機器。
- 執行 hostname 命令,檢查能否正常返回主機名。
(1)如 果 該 命 令 報 錯, 請 檢 查 是 否 為 該 命 令 定 義 了 別 名(alias), 比 如 在 .bash_profile 文件或者 .bashrc 文件中設置了 alias hostname='/ usr/bin/**' 的別名。確保 hostname 命令能夠正常返回主機名。
(2)如果該命令正常執行,記錄返回的主機名並繼續下一步。
- 檢查能否 ping 通記錄的主機名。
(1)如果無法 ping 通,請參考 127.0.0.1[$Hostname],將記錄的主機名綁 定到 /etc/hosts 文件中。
(2)如果可以 ping 通,請繼續下一步。
- 檢查 /etc/sysconfig/network 文件中的
Hostname 是否與 /etc/hosts 文件中的主機名一致。
(1)如果不一致,請修改 /etc/sysconfig/network 文件中的 Hostname 參數
值,使其與 /etc/hosts 文件中的主機名一致。
(2)/etc/sysconfig/network 文 件 中 不 存 在 Hostname 配 置, 請 參 考
hostnamectl set-hostname [$Hostname] 命令更新主機名。
(3)如果一致,請繼續下一步。
- 重新啟動消息隊列 RocketMQ 版的客戶端,確認不再提示有關未知主機名
的異常信息。
發送消息時報錯消息不合法
【問題描述】:
發送消息時報錯消息不合法。
【問題原因】:
一般是消息屬性、消息內容不合法,不合法的情況有:
- 消息為空;
- 消息內容為空;
- 消息內容長度為 0;
- 消息內容超過限定長度。
Tcp 協議開源 sdk 連接 mq 失敗
【問題描述】:
Tcp 協議開源 sdk 無法連接 mq,代碼層面報錯。
【問題回答】:
可能原因:
開源 sdk 接入阿里雲,阿里雲都是與各個開源語言的 sdk 做過適配的。因此一定需要使用阿里雲官方文檔上推薦的各個語言的 sdk 版本,如果使用的開源版本非阿里雲提供的官網推薦使用的 sdk 版本,那麼是無法成功連接到阿里雲 mq 的。