天天看點

發送問題排查 | 《Rocket MQ 使用排查指南》第二章

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

點選免費下載下傳

《Rocket MQ 使用排查指南》>>>

發送問題排查 | 《Rocket MQ 使用排查指南》第二章
也可以PC端點選 https://developer.aliyun.com/topic/download?id=820 下載下傳

發送問題排查

用戶端發送性能問題

發送消息耗時久

【問題描述】:

通過消息軌迹查詢到,MQ 消息發送的耗時達到秒級之上。

發送問題排查 | 《Rocket MQ 使用排查指南》第二章

【排查步驟】:

  1. 首先确認該現象是偶發還是頻繁出現。
  2. 其次确認是部分機器發送有問題還是大量機器發送都存在此現象。
  3. 接着檢查是少量的 topic 發送有此現象還是大部分機器如此。
  4. 确認您的應用機器的外網帶寬。
  5. 檢查發送消息的時間占比。

【問題原因】:

  1. 如果是偶發現象,檢查現象存在期間您發送端的 TPS、網絡狀态以及出口 ip 的連接配接情況、确認期間應用是否有 Full GC(Full GC 會造成網絡延遲 ),可 結合 ons.log 來綜合分析。
    1. 如果部分機器有問題,那麼登入該機器,檢視網絡流量以及 tps。
  2. 若用戶端帶寬過小,可建議更新帶寬。
  3. 如果頻繁現象,建議收集好資訊回報給技術支援人員,技術支援人員需要查 看下後端的 topic 叢集是否有問題。

延時消息發送性能問題

【問題描述】: 業務大量使用發送延時消息,可以指定延時 15 天之後再投遞消費嗎?

看開源的代碼是單線程去處理這些延遲消息的隊列, 如果有大量消息在隊列中, 性能上也是沒有問題的嘛。

【問題回答】:

延時消息我們會先存 DB,在指定的時間掃描 DB,再将消息存儲到 broker 上, 投遞給消費端。并且這個存 DB 和掃碼 DB 都是後端完成的。

也是因為這個存儲 DB 和掃碼的 DB 的損耗,是以我們的定時消息性能是沒有普 通消息高的。

普通消息是直接發送存儲到 broker 上的。延時消息就是多了兩層的消 耗的。 普通消息和延遲消息是不一樣的,這二者不存在轉換的關系的。

為什麼用普通消息的 topic 發送延遲消息也可以成功

topic 主題類型分為好幾種,但是測試發現無論使用普通消息類型還是延時定時 消息類型都一樣沒問什麼差別。

比如建立的普通消息類型 topic 但是發送延時消息也是可以使用的。總結來 說 :topic 消息類型有作用嗎。

往普通消息類型 topic 當中發送延時消息,是可以成功,但是不保證一定成功, 也不保證相應的性能。

但是如果您嚴格按照消息類型建立對應的 topic,并且發送相應類型的消息,性 能是會得到保障的。

用戶端發送常見異常報錯

啟動發送端時報錯 No route info of this topic

具體報錯異常如圖所示。

發送問題排查 | 《Rocket MQ 使用排查指南》第二章

【排查思路】:

  1. 确認您在 MQ 控制台 已建立 topic ,确認 topic 拼寫及對應,控制台查詢比 對 topic。
  1. 檢查您代碼的接入點配置,是否是 MQ 控制台上的接入點配置。
  2. 确認 NameServer 可以連接配接,telnet 接入點 + 端口,看是否能 telnet 通。
  3. 确認 NameServer 可用,curl 接入點,将獲得的位址和端口号也 telnet 下, 确認通暢。
  4. 确認 topic 權限可用,檢查您代碼中配置的 AK、SK 所屬的賬号是否擁有此 topic 的釋出訂閱權限發送或消費權限異常。
    1. 看是否發送消息的執行個體和發送端是在同一個 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 等異常資訊。

發送問題排查 | 《Rocket MQ 使用排查指南》第二章
  1. 共享叢集,當時 broker 壓力大,會出現這個問題。
  2. broker 出現了網絡,磁盤,IO 等抖動時,會出現這個問題。
  1. 首先看下是短暫偶爾抖動還是持續,持續多長時間?
  2. 如果是偶爾抖動,是系統更新或 broker 壓力大 , 或者抖動異常 , 但是 sdk 有 重試政策 , 會重試到其它的 broker,不影響消息的發送。
  3. 如果是長時間持續出現這種情況 , 那麼需要收集一下資訊:uid/ 執行個體 id/ 地域 /topic 等給到技術支援人員,技術人員需要核實下後端叢集狀态是否正常。
  4. 報錯建議您在自己的業務代碼層面 try...catch 進行重試。

1.8.4 版本的 skd 會自定進行 brokerbusy 的重試【不一定保證重試到其他的broker 一定是成功的】。

發送端出現發送逾時異常

在ons.log日志中出現RemotingConnectException: connect to <118.190.213.56:80>failed 或者 RemotingTimeoutException 等異常資訊。

發送問題排查 | 《Rocket MQ 使用排查指南》第二章
  1. 首先可以确認該時間段内是否屬于服務更新時間段内 ( 可以看官網公告 ) 這 是 MQ 服務更新過程中 , 會出現短暫的網絡閃斷 , 但是我們的 mq 服務是集 群部署的 , 一台網絡的閃斷是不會影響消息的。
  2. 在自己的應用伺服器上執行 telnet brokerip port,确認服務端的端口是否 通暢。
  3. 執行 ping brokerip , 檢視網絡是否延遲。同時檢查網絡監控名額,觀察在問 題時間點流量是否有下降的情況。如果 ping 或者 telnet 不通,需要檢查下 伺服器的防火牆,網絡設定等。
  4. 檢查應用的網絡帶寬情況,是否打滿。
  5. 可執行 jstack -l 程序号 > 檔案名 .dump 來分析堆棧資訊,判斷當時應用系 統有沒有 Full GC 現象 (Full GC 會造成一定的網絡延遲 )。
  6. 确認下使用的 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,發送報錯。

發送問題排查 | 《Rocket MQ 使用排查指南》第二章

到 {home}/logs/rocketmqlogs 路徑下檢視 mq 的日志。

從日志當中看到有連接配接報錯。

發送問題排查 | 《Rocket MQ 使用排查指南》第二章

根據報錯懷疑是接入點接入點接入的有問題

代碼當中填入的是 http 的接入點,但是使用的是 tcp 的 sdk,應該使用控制台提供的 tcp 的接入點。

需要注意的是,使用什麼連接配接類型的 sdk,就一定要對應使用控制台提供的對應連接配接類型的接入點,如果使用錯誤,那麼代碼将不會運作成功。

Php 的 http 接入方式發送消息失敗

使用 php 的 http 接入方式,發送消息報錯,導緻消息發送失敗。

報錯如圖。

發送問題排查 | 《Rocket MQ 使用排查指南》第二章

【問題回答】:

internal error 一般是後端記錄有類似于網絡抖動的報錯異常。

遇到此類錯誤,需要将執行個體 id/ 地域 /topic/sdk 語言版本等資訊收集回報給到技術人員進行後端伺服器核實。

發 送 消 息 報 錯 NumberFormatException: For inputstring: "//XXX"

啟動發送端,發送消息報錯 NumberFormatException: For input string: "//XXX。

發送問題排查 | 《Rocket MQ 使用排查指南》第二章

出現這種問題肯定是 sdk 版本過低的原因,底層調用的 MQ 版本與 pom 裡配置 的 ons-sdk 版本不一緻。

【解決方案】:

● 采用 mvn dependency:tree 分析依賴樹之間的關系。

● 如果是打出去的是 jar 包,将生成的 jar 解壓,然後在 lib 目錄下确認下 ons 的 版本是否正确,如下圖所示:

發送問題排查 | 《Rocket MQ 使用排查指南》第二章

發送消息報錯權限異常

發送消息失敗,報錯:AuthenticationException 或者是

發送問題排查 | 《Rocket MQ 使用排查指南》第二章

【問題原因】:

代碼中配置的 AK、SK 所歸屬的賬号,與建立 Topic 或者是 GID 的賬号并不匹 配,導緻權限錯誤。

【解決辦法】:

  1. 檢查代碼當中配置的 ak 是否有調用 topic 發送消息的權限。
  1. 核實下 sdk 的版本,如果是平時發送消息都是正常,偶爾會出現這種異常 報錯資訊。可以看下 sdk 版本是否是 1.7.9 版本的。如果是,建議更新 sdk。1.7.9 版本的 sdk 在鑒權的時候,的确會容易出現鑒權失敗的問題, 此版本在健全上有一些 bug。
  2. 檢查下代碼當中的接入點是否配置正确,可以 debug 看下,取到的接入點是 否和控制台提供的接入點完全一緻。
  3. 檢查下代碼當中配置的 topic 是否與控制台建立的 topic 完全一緻。
  4. 如果以上确認過都沒有問題,需要收集執行個體 id/ 地域 /topic/sdk 版本等資訊 給到技術人員進行後端伺服器狀态核實。

發送消息時日志報錯

發送消息的時候,日志記錄有報錯

com.aliyun.openservices.shade.com.alibaba.rocketmq.client.exception.MQBrokerException:

CODE: 1 DESC: [REJECTREQUEST]Broker in slave mode

發送問題排查 | 《Rocket MQ 使用排查指南》第二章

這個報錯是因為優化後端叢集節點的時候導緻的報錯。對使用是沒有影響的哈, 隻是日志會有異常記錄下來。

也可以再觀察下,如果是持續大量報錯,并且消息會發送失敗,需要提供執行個體 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 太大

【解決方案】:

  1. 消息體大小最大為 4MB, 一般建議發送的消息體在 4kb 之内 ( 性能最佳 )。
  2. 消息屬性最大為 32kb,一般建議發送的消息屬性在 1kb 之内 ( 性能最佳 )。
  3. 4MB 這個上限值不能修改,這個會影響全局性能。如果消息體的确很大,建 議側優化消息體的内容,避免發送大消息或者帶有連結位址的消息,或者可 以縮短或者分兩條發送。

應用部署在 edas 當中發送消息失敗

mq 的應用部署在 edas 當中,但是發送消息失敗。

發送問題排查 | 《Rocket MQ 使用排查指南》第二章

通過發送報錯日志看到 是 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 插件的版本。

發送問題排查 | 《Rocket MQ 使用排查指南》第二章

發送時報錯 fetch name server address exception

發送消息的時候日志出現 fetch name server address exception 異常資訊。

發送問題排查 | 《Rocket MQ 使用排查指南》第二章

根據代碼配置中的 ONSAddr 這個位址來擷取 NAMESRV_ADDR 時失敗了。

  1. 檢查代碼配置,看配置的 ONSAddr 是否和控制台上的一緻,有可能配置錯了,将 NAMESRV_ADDR 當成了 ONSAddr,進行了如下圖配置。
發送問題排查 | 《Rocket MQ 使用排查指南》第二章
  1. nslookup 接入點的域名看下。檢查 dns 是否正确。正确情況下,會擷取到綁定。

這個域名的 ip,在 ping 下 ip 是否是通的

nslookup onsaddr-internet.aliyun.com

發送消息報錯 not set any response code

發送延遲消息報錯。

發送問題排查 | 《Rocket MQ 使用排查指南》第二章

設定的 message properties 中某個屬性的值過長,造成發送失敗。 【排查過程】:

  1. 查詢問題節點的消息,mq 控制台對應的接口是 ConsoleMessageGetByPagedTopic,openApi 對應的接口是 OnsMessagePageQueryByTopic。
  2. 登入 mq 控制台,打開浏覽者開發工具(win os: F12 mac os: command+ F12),找到如下圖所示的接口,檢視傳回的 response. 将其進行 json 化, 檢視 properties 裡是否存在長度比較長的屬性值。
發送問題排查 | 《Rocket MQ 使用排查指南》第二章
  1. 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.

異常如圖

發送問題排查 | 《Rocket MQ 使用排查指南》第二章

此問題不是權限報錯,而是 AK 出現了問題,去 ak 中心根據 ak 擷取子使用者資訊出錯了,可以重新換個 ak 試試。

啟動發送者時報錯 UnknownHostException

啟動消息隊列 RocketMQ 版的用戶端時提示異常 UnknownHostException資訊。

導緻此問題的主要原因是用戶端無法擷取系統的主機名(Hostname)或者系統的 IP 位址。

請參考以下步驟進行排查:

  1. 登入用戶端所在機器。
  2. 執行 hostname 指令,檢查能否正常傳回主機名。

(1)如 果 該 命 令 報 錯, 請 檢 查 是 否 為 該 命 令 定 義 了 别 名(alias), 比 如 在 .bash_profile 檔案或者 .bashrc 檔案中設定了 alias hostname='/ usr/bin/**' 的别名。確定 hostname 指令能夠正常傳回主機名。

(2)如果該指令正常執行,記錄傳回的主機名并繼續下一步。

  1. 檢查能否 ping 通記錄的主機名。

(1)如果無法 ping 通,請參考 127.0.0.1[$Hostname],将記錄的主機名綁 定到 /etc/hosts 檔案中。

(2)如果可以 ping 通,請繼續下一步。

  1. 檢查 /etc/sysconfig/network 檔案中的

Hostname 是否與 /etc/hosts 檔案中的主機名一緻。

(1)如果不一緻,請修改 /etc/sysconfig/network 檔案中的 Hostname 參數

值,使其與 /etc/hosts 檔案中的主機名一緻。

(2)/etc/sysconfig/network 文 件 中 不 存 在 Hostname 配 置, 請 參 考

hostnamectl set-hostname [$Hostname] 指令更新主機名。

(3)如果一緻,請繼續下一步。

  1. 重新啟動消息隊列 RocketMQ 版的用戶端,确認不再提示有關未知主機名

    的異常資訊。

發送消息時報錯消息不合法

發送消息時報錯消息不合法。

一般是消息屬性、消息内容不合法,不合法的情況有:

  1. 消息為空;
  2. 消息内容為空;
  3. 消息内容長度為 0;
  4. 消息内容超過限定長度。

Tcp 協定開源 sdk 連接配接 mq 失敗

Tcp 協定開源 sdk 無法連接配接 mq,代碼層面報錯。

可能原因:

開源 sdk 接入阿裡雲,阿裡雲都是與各個開源語言的 sdk 做過适配的。是以一定需要使用阿裡雲官方文檔上推薦的各個語言的 sdk 版本,如果使用的開源版本非阿裡雲提供的官網推薦使用的 sdk 版本,那麼是無法成功連接配接到阿裡雲 mq 的。