基于Arthas的應用在線診斷平臺實踐
背景介紹
在日常系統運行過程中,故障總是不期而遇。一旦出現故障通常是查監控,翻各種日志,從大量的日志中尋找蛛絲馬跡。如果問題現場的日志記錄缺失,會嘗試在本地重現問題并調試解決,本地難以重現的,只能再加日志,再部署,再重現,然后再查日志,效率較低。對于復雜一些的比如程序性能問題,如何定位性能瓶頸,一不小心又要回到加日志、部署、查日志、再加日志的老路,不僅效率不高,也破壞了問題現場。
所以針對以上問題,我們的目標是建立一個Java應用在線診斷平臺,讓開發人員無需登錄機器或修改系統,就可以從日志、內存、線程、類信息、調試、機器和系統屬性等各個方面對應用進行診斷,提升開發人員診斷問題的效率和能力。
系統架構
我們期望有一套架構,讓開發人員以Web UI的方式使用各類在線診斷能力。
架構概覽
架構概覽
瀏覽器
瀏覽器是開發人員進行在線診斷的入口,tunnel server通過Web UI的方式提供在線診斷能力,支持復雜的交互場景。
tunnel server
提供兩個方面的功能,分別是:
管理功能
瀏覽器通過http與tunnel server的12201端口進行交互;
連接指定IP的arthas agent機器、斷開指定IP的arthas agent機器、查看指定IP的arthas agent生成的文件。
診斷功能
瀏覽器通過websocket與tunnel server的12202端口進行交互;
支持各種arthas診斷指令:dashboard、heapdump、thread、vmtool等。
應用程序服務器
arthas agent作為websocket客戶端與tunnel server的12202端口進行交互;
arthas agent通過attach應用進程實現對應用進程的診斷。
原理介紹
核心流程
流程說明:
1.1 tunnel server 監聽12201端口,該端口用于展示Web UI
1.2 tunnel server監聽12202端口,該端口用于與瀏覽器進行websocket交互,也用于與arthas agent進行websocket交互
1.3 應用程序通過引入arthas pom依賴,在應用部署的時候將arthas安裝包安裝到服務器上
2.1 通過在瀏覽器上訪問:
http://tunner_server_ip:12201,打開Web UI
2.2 在Web UI上輸入要診斷的服務器IP,點擊Connect,建立與tunner server 12202端口的websocket連接,發送請求為:
ws://tunner_server_ip:12202/ws?method=connectArthas&id=服務器IP
2.3 tunner server根據服務器IP獲取與arthas agent的control connection
2.4 如果control connection沒有建立,則通過訪問
http://arthas_agent_IP:12230?tunnerserver=ws://tunner_server_ip:12202/ws,觸發arthas agent初始化、attach應用進程。
2.5 arthas agent創建與tunner server的websocket連接:
- arthas agent tunnel client connect to tunnel server with URL: ws://tunner_server_ip:12202/ws?method=agentRegister
- tunnel server response a text frame message: response:/?method=agentRegister&id=服務器IP
此時創建的websocket連接稱為:control connection。
2.6 control connection已創建成功,則向arthas agent tunnel client發送:response:/?method=startTunnel&id=服務器IP&clientCnotallow=connectionIDxxx,請求建立連接;
arthas agent tunnel client收到startTunnel請求后,新建與tunnel server的連接,并發送:ws://tunner_server_ip:12202/ws/?method=openTunnel&clientCnotallow=connectionIDxxx&id=服務器IP
此時創建的websocket連接稱為:tunnel connection;
同時創建與arthas agent的本地連接:ws://127.0.0.1:3658/ws,此時創建的連接稱為:local connection
3.13.2 執行診斷命令鏈路如下:
交互邏輯
關鍵問題分析
arthas本身提供了tunner server功能,我們主要需要解決的有兩個問題:
- 如何安裝arthas到指定服務器
- 如何按需加載arthas agent,即只有對指定服務器進行診斷的時候才進行arthas agent的初始化
安裝Arthas
獨立安裝運維
將arthas打包進操作系統鏡像中,保證新初始化的ECS實例中含有最新版本的arthas;對于已經存在的ECS實例則需要想辦法進行arthas版本更新。
通過SSH腳本
第2.2步驟當對指定服務器進行診斷的時候,在tunnel server或其他旁路系統通過ssh方式將arthas安裝包拷貝的指定服務器。
通過javaagent
在應用進程初始化的時候,加載自定義的javaagent,該javaagent實現下載、解壓arthas的功能。
第2.2步驟當對指定服務器進行診斷的時候,tunnel server或其他旁路系統通過與指定服務器javaagent通訊,通過javaagent完成arthas下載、解壓。
通過POM
應用通過引入arthas pom,將arthas打包進應用部署包中。
初始化ArthasAgent
復用Web Server端口
在應用工程中新建一個Controller,該Controller實現arthas agent初始化功能。
tunnel server通過現有的Web Server訪問Controller接口觸發arthas agent初始化。
注意:
- 需要tunnel server能夠訪問Web Server端口
- 不同應用的Web Server Context路徑可能不一樣
通過獨立的HTTPServer
創建獨立的HTTP Server,主要是為了使得tunnel server能夠訪問新監聽的端口,解決【復用Web Server】端口面臨的兩個問題。
注意:
- 新監聽的http端口需要對tunnel server開放
- http server的context路徑都是一致的
通過HSF/gRPC/dubbo等RPC
根據應用使用的RPC框架,新建對應的RPC Provider,tunnel server直接調用指定IP的RPC Provider完成arthas agent的初始化。該方式的好處是不用新開放監聽端口。
注意:
- RPC Client需要能夠調用指定IP的RPC Provider
通過MQ
tunnel server作為MQ Producer發送報文(報文中包含指定服務器的IP)到MQ Broker,應用中新建MQ Consumer消費tunnel server的報文,如果報文中IP與本機一致則處理,不一致則丟棄。
通過Apollo等配置中心
思路與【通過MQ】一致,按照apollo等配置中心相關API進行實現。
通過Redis緩存
思路與【通過MQ】一致,按照Redis相關通訊機制進行實現。
通過SSH
tunner server或旁路系統有權限直接ssh指定服務器,通過腳本方式觸發arthas agent初始化。
展示效果
tunnel server
在AgentId的文本框里輸入要診斷的服務器IP,稍等一會就可以進行診斷了。
web console
指定服務器Web UI
dashboard
dashboard
immediacy
thread示例
thread
real time
monitor示例
monitor
option
JVM options示例
jvm options
console
console
terminal
terminal與tunner server UI基本一致,不同的是該terminal是直接訪問的目標服務器。
總結
以上方案只是簡單的應用,期望以后可以不斷的迭代優化。