天天看點

生産環境MQTT消息響應緩慢的故障排查

  生産環境的充電樁項目一直運作平穩,使用者在H5頁面上操作,掃描充電樁,而後可以支付,進入對應的界面可以控制該充電樁的放電、停電。

  具體的控制流程為,使用者在頁面通過HTTPS協定與伺服器進行互動,伺服器接收到請求後,組裝參數,發送消息到mqtt伺服器(RabbitMQ),而後充電樁的Mqtt用戶端即可收到該條消息。充電樁對頁面的消息回報剛好是一個相反的過程。

  該項目上線後,消息的發送到硬體響應平均時間基本在2s左右(視當地的4G網絡信号)。但一天下午,小區的客戶回報,整個過程變得特别慢,下單後放電成功,但頁面遲遲不會跳轉到放電展示的界面,而且點選頁面停電按鈕,也不會生效。

  首先,檢視伺服器上的H5子產品的日志,發現但凡是傳入該子產品Mqtt消息的,伺服器上都已經成功處理,沒有延遲的情況。是以懷疑是當地充電樁硬體的信号問題(此前不久曾發生某小區大規模4G無信号、弱信号的情況)。為了保險,在辦公室裡調試并安裝了一套硬體裝置,模拟線上的情況,發現下發,響應很及時,沒有出現延遲的情況。是以當即讓現場人員檢查,但現場人員經過十幾分鐘測試,反應4G信号沒有問題。

  沒辦法,隻能再次多次的在辦公室進行問題複現,現場也有人員進行配合測試。結果确實發現有消息漏傳到伺服器的情況。即,上傳成功的消息,伺服器都處理成功,沒有上傳成功的,伺服器沒有處理,頁面隻能處于等待狀态并進入後續的等待處理流程。此時,為了驗證充電樁是否真的漏傳消息,還是因為什麼别的原因伺服器沒有處理該條消息,開啟了一個Mqtt用戶端,并設定好環境,連上生産環境的伺服器後,調到對應的topic并開啟消費端,結果發現,充電樁的所有消息上傳是正常的,但伺服器這邊确實沒有接收到。此時,想到會不會是有多個程式,設定了相同的clientid,同時在消費生産環境的消息。經過各個伺服器(允許連入生産環境IP)的排查,發現确實有一個消費端,與生産環境的MQTT消息消費子產品分享了所有消息。将該消費端的程序kill掉,生産環境立即恢複正常。

  其實,這個問題之前已多次發生,但每次都會以不盡相同的場景出現,而且由于相同終端ID消費消息政策的不同,還可能出現有些時候測試響應及時,有些響應卻很慢的情況,對排查問題造成了幹擾。比如起初調試硬體mqtt消息時,由于硬體工程師對該協定細節不甚清楚,結果将所有的硬體燒錄了完全相同的代碼,即clientid也相同。這樣,當兩個以上硬體同時線上時,就相當于兩個clientId相同的消費端同時開啟,這樣原本發送給某一個消費端的消息就可能會被另一個接收,目标消費端不會有反應,而伺服器在發現目标消費端沒有反應後,會啟動重發機制,最終目标消費端接收到消息後,會給人造成一種通信延遲的假象。一開始隻有一個硬體調試時,一切正常,但當硬體開啟了幾個之後,就表現出網絡不暢的現象,一度懷疑是辦公區域的網絡問題。其實是幾個終端共同消費了同一通道的所有消息,導緻漏收。雖然有重發機制保障整個流程能夠完整執行,但是整個過程會顯得特别卡頓,整個執行周期相當漫長。之前在使用kafka的過程中,同樣也遇到過類似的問題。

  不過在大資料量處理過程中,該特性卻是一個可以用來分散流量的解決方案。比如海量終端生産資料上傳到消息隊列中,開一個消費端,可能根本無法承受這麼大的資料流量,無法及時的處理,是以此時必須在不同伺服器,開啟多個終端,使用相同的終端ID,才能分享并及時處理該批消息。

  記錄一下,涉及消息隊列的問題排查中,這個問題點值得關注。