天天看點

RocketMQ生産部署架構設計,Java崗

随着網際網路快速發展,微服務,soa 等服務架構模式正在被大規模的使用,現在分布式系統一般由多個獨立的子系統組成,多個子系統通過網絡通信互相協作配合完成各個功能。

有很多用例會跨多個子系統才能完成,比較典型的是電子商務網站的下單支付流程,至少會涉及交易系統和支付系統。而且這個過程中會涉及到事務的概念,即保證交易系統和支付系統的資料一緻性,此處我們稱這種跨系統的事務為分布式事務。

具體一點而言,分布式事務是指事務的參與者、支援事務的伺服器、資源伺服器以及事務管理器分别位于不同的分布式系統的不同節點之上。

什麼是 arthas?

arthas 是一款開源線上診斷工具,采用指令行互動模式,支援 web 端線上診斷,同時提供豐富的 tab 自動補全功能,進一步友善進行問題的定位和診斷。這是一款開源一年多 github star 2 萬,99% 的阿裡研發小哥都在用的 java 終極診斷利器!相對比直接下載下傳使用,我推薦開發者可以試一下通過 ide插件 cloud toolkit 中使用arthas 來實作一鍵遠端診斷功能。

得益于 arthas 強大且豐富的功能,讓 arthas 能做的事情超乎想象。下面僅僅列舉幾項常見的使用情況,更多的使用場景可以在熟悉了 arthas 之後自行探索。

是否有一個全局視角來檢視系統的運作狀況?

為什麼 cpu 又升高了,到底是哪裡占用了 cpu ?

運作的多線程有死鎖嗎?有阻塞嗎?

程式運作耗時很長,是哪裡耗時比較長呢?如何監測呢?

這個類從哪個 jar 包加載的?為什麼會報各種類相關的 exception?

我改的代碼為什麼沒有執行到?難道是我沒 commit?分支搞錯了?

遇到問題無法線上上 debug,難道隻能通過加日志再重新釋出嗎?

有什麼辦法可以監控到 jvm 的實時運作狀态?

arthas 的指令、功能在其官方文檔有詳細介紹,下文将介紹一下近期幾個使用場景。

場景 1:定位壓測時的性能瓶頸

平時伺服器請求都很正常。壓測時,依賴的服務、資料庫也都沒有到達瓶頸,但是機器的 cpu 全部飄紅,why?

通過 jstack 指令,隻能看到某一時刻的堆棧,沒有抓到真兇。

thread 檢視目前線程資訊,檢視線程的堆棧。

thread -n 3 -i 10000 可以統計 10 秒内最忙的 3 個線程,并且列印它們的堆棧,很容易發現問題。最終發現的問題比較簡單:日志中列印了 location 的資訊,包括 類名、方法名和行号。

動态擷取代碼的方法名、行号等資訊,通常是通過 new throwable() -> 列印 throwable 的堆棧 -> 截取堆棧中最頂層的業務代碼 -> 拆分字元串擷取類、方法、行号等資訊, 列印堆棧對性能損耗是比較大的。

RocketMQ生産部署架構設計,Java崗

場景 2:檢測偶發的逾時

有段時間,總是碰到幾次偶爾的逾時,但是看日志都正常,鷹眼的調用鍊路都完全 ok,沒有哪一步資料庫操作或者 hsf 調用是特别慢的。

各種監控統計的時間次元的耗時,都十分正常,無法找到那個 rt 的尖刺。

想到了可能是日志的問題,但是沒有證據支撐。

trace 指令能監控每一步的耗時,并且可以配合條件表達式,當耗時超過 xx ms 時列印詳細日志。

找台機器,輸入指令,後面的就是靜等了。再次出現 rt 尖刺時,能夠捕捉到耗時的分布情況。

RocketMQ生産部署架構設計,Java崗

通過 arthas 拿到的結果,定位到是日志列印的問題。同步日志改為異步日志後,問題解決。

場景3:debug?那要是動态位元組碼生成咋辦?

之前碰到過一個 json 序列化時輸出的數字帶不帶引号的問題。當時各種 debug、看代碼,發現是通過 asm 動态位元組碼的方式生成的序列化類。到這完全放棄了,debug 已經無法定位問題了。當時通過另外一種方式避免了這種問題。

反過來看這個問題的時候,我們可以通過 arthas 的 jad 指令,反編譯動态位元組碼生成的類,結合 watch 等指令,定位排查問題。

jad——反編譯指定已加載類的源碼

RocketMQ生産部署架構設計,Java崗

還可以通過 mc(menory compiler), redefine 指令線上熱更新代碼,歡迎探索。