上一章: 什麼是消息隊列Rocket MQ| 《Rocket MQ 使用排查指南》第一章>>> 下一章: 消費問題排查 | 《Rocket MQ 使用排查指南》第三章>>> 點選免費下載下傳 《Rocket MQ 使用排查指南》>>>

發送問題排查
用戶端發送性能問題
發送消息耗時久
【問題描述】:
通過消息軌迹查詢到,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_existfor 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 的。