個輕量的企業(yè)級Web的控制終端程序,匯集了大多數(shù)同類產品優(yōu)點于一身,支持SSH2/lrzsz、(RDP/RFB/Telnet)、審計和錄屏等
git clone https://github.com/wl4g/xcloud-webconsole.git # 上游,最新
# git clone https://gitee.com/wl4g/xcloud-webconsole.git
cd xcloud-webconsole/scripts
./build.sh # 交叉編譯為Windows程序
# build.bat # 交叉編譯為Linux程序
因為webconsole是基于HTML的,瀏覽器的復制和粘貼功能受到安全機制的限制,只能在HTTPS下使用,當然若不想麻煩,也可忽略此步驟,直接使用HTTP本地測試,只是不能使用瀏覽器的復制和粘貼功能。
127.0.0.1 webconsole.wl4g.debug
sudo mkdir -p /etc/nginx/conf.d && \
cat > /etc/nginx/conf.d/webconsole.conf <<EOF
# Generated by WebConsole docs sample.
# WebConsole Webapps pages.
server {
listen 443;
server_name webconsole.sunwuu.fat;
ssl on;
ssl_certificate certs/_wildcard.wl4g.debug.pem;
ssl_certificate_key certs/_wildcard.wl4g.debug-key.pem;
ssl_session_timeout 5m;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:ECDHE:ECDH:AES:HIGH:!NULL:!aNULL:!MD5:!ADH:!RC4;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_prefer_server_ciphers on;
location / {
root /usr/share/nginx/html/webconsole;
index index.html;
}
}
# WebConsole APIs.
server {
listen 26088 ssl;
server_name webconsole.sunwuu.fat;
ssl_certificate certs/_wildcard.wl4g.debug.pem;
ssl_certificate_key certs/_wildcard.wl4g.debug-key.pem;
ssl_session_timeout 5m;
ssl_prefer_server_ciphers on;
ssl_protocols TLSv1 TLSv1.1 TLSv1.2;
ssl_ciphers ECDHE-RSA-AES128-GCM-SHA256:HIGH:!aNULL:!MD5:!RC4:!DHE;
location / {
proxy_http_version 1.1;
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
proxy_set_header X-real-ip $remote_addr;
proxy_set_header X-Forwarded-For $remote_addr;
proxy_pass http://127.0.0.1:16088;
}
}
EOF
sudo chmod 755 /etc/nginx/conf.d/webconsole.conf
sudo systemctl restart nginx
chrome://settings/security
管理證書 -> 受信任的根證書頒發(fā)機構 -> 導入 然后重啟chrome瀏覽器嘗試訪問: https://webconsole.wl4g.debug
curl http://localhost:16089/metrics
# HELP goroutines_num Number of goroutines
# TYPE goroutines_num gauge
goroutines_num 16
# HELP mysql_active_conn Current active connections of MySQL
# TYPE mysql_active_conn gauge
mysql_active_conn{dbconnectstr="gzsm:******@tcp(10.0.0.160:3306)/devops_dev?charset=utf8",host="10.0.0.172"} 1
# HELP ssh2_active_dispatch_channels Current active channels of SSH2 dispatcher
# TYPE ssh2_active_dispatch_channels gauge
ssh2_active_dispatch_channels{host="10.0.0.172",user="admin"} 0
# HELP threads_num Number of threads
# TYPE threads_num gauge
threads_num 8
# HELP virtual_free_memory Size of virtual free memory
# TYPE virtual_free_memory gauge
virtual_free_memory 1.731424256
# HELP virtual_total_memory Size of virtual total memory
# TYPE virtual_total_memory gauge
virtual_total_memory 8.50089984
說明:界面未設置css樣式的最精簡測試頁面
是不是在實際開發(fā)工作當中經(jīng)常碰到自己寫的代碼在開發(fā)、測試環(huán)境行云流水穩(wěn)得一筆,可一到線上就經(jīng)常不是缺這個就是少那個反正就是一頓報錯抽風似的,線上調試代碼又很麻煩,讓人頭疼得抓狂;而且debug不一定是最高效的方法,遇到線上問題不能debug了怎么辦。原先我們Java中我們常用分析問題一般是使用JDK自帶或第三方的分析工具如jstat、jmap、jstack、 jconsole、visualvm、Java Mission Control、MAT等。但此刻的你沒有看錯,還有一款神器Arthas工具著實讓人吃驚,可幫助程序員解決很多繁瑣的問題,使得加班解決線上問題成為過去的可能性大大提高。
Arthas是一個Java診斷工具,由阿里巴巴中間件團隊開源,目前已在Java開發(fā)人員中被廣泛采用。Arthas能夠分析,診斷,定位Java應用問題,例如:JVM信息,線程信息,搜索類中的方法,跟蹤代碼執(zhí)行,觀測方法的入?yún)⒑头祷貐?shù)等等。并能在不修改應用代碼的情況下,對業(yè)務問題進行診斷,包括查看方法的出入?yún)ⅲ惓#O(jiān)測方法執(zhí)行耗時,類加載信息等,大大提升線上問題排查效率。簡單的話:就是再不重啟應用的情況下達到排查問題的目的。
在日常開發(fā)中,當我們發(fā)現(xiàn)應用的某個接口響應比較慢,這個時候想想要分析一下原因,找到代碼中耗時的部分,比較容易想到的是在接口鏈路的 IO 操作上下游打印時間日志,再根據(jù)幾個時間點的日志算出耗時長的 IO 操作。這種方式?jīng)]有問題,但是加日志需要發(fā)布,既繁瑣又低效,這個時候可以引入一些線上 debug 的工具,arthas 就是很好的一種,除了分析耗時,還可以打印調用棧、方法入?yún)⒓胺祷兀惣虞d情況,線程池狀態(tài),系統(tǒng)參數(shù)等等,其實現(xiàn)原理是解析 JVM 在操作系統(tǒng)中的文件,大部分操作是只讀的,對服務進程沒有侵入性,因此可以放心使用。
創(chuàng)建一個springboot項目并打包成arthas-demo-1.0.jar,啟動arthas-demo-1.0.jar
代碼示例如下
package cn.itxs;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
?
@SpringBootApplication
public class App
{
public static void main(String[] args) {
SpringApplication.run(App.class,args);
new Thread( () -> {
while (true) {
String str = UUID.randomUUID().toString().replaceAll("-", "");
}
},"cpu demo thread").start();
?
new Thread( () -> {
while (true) {
String str = UUID.randomUUID().toString().replaceAll("-", "");
try {
TimeUnit.MILLISECONDS.sleep(10);
} catch (InterruptedException e) {
e.printStackTrace();
}
}
},"cpu with sleep thread").start();
}
}
# 下載`arthas-boot.jar`這種也是官方推薦的方式
curl -O https://arthas.aliyun.com/arthas-boot.jar
# 啟動arthas-boot.jar,必須啟動至少一個 java程序,否則會自動退出。運行此命令會自動發(fā)現(xiàn) java進程,輸入需要 attach 進程對應的序列號,例如,輸入1按回車則會監(jiān)聽該進程。
java -jar arthas-boot.jar
# 比如輸入JVM (jvm實時運行狀態(tài),內存使用情況等)
package cn.itxs.controller;
?
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
?
import java.util.concurrent.TimeUnit;
?
@RestController
@RequestMapping("/thread")
public class ThreadController {
private Object obj1 = new Object();
private Object obj2 = new Object();
?
@RequestMapping("/test")
@ResponseBody
public String test(){
new Thread(() -> {
synchronized (obj1){
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
synchronized (obj2){
System.out.printf("thread 1執(zhí)行到此");
}
}
}
},"thread 1").start();
?
new Thread(() -> {
synchronized (obj2) {
synchronized (obj1){
System.out.printf("thread 2執(zhí)行到此");
}
}
},"thread 2").start();
return "thread test";
}
}
SpringBoot啟動類
package cn.itxs;
?
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
?
@SpringBootApplication
public class App
{
public static void main(String[] args) {
SpringApplication.run(App.class,args);
}
}
# 訪問頁面http://192.168.50.100:8080/cpu/test
# 儀表盤命令,通過上面我們可以發(fā)現(xiàn)線程ID為29也即是線程名稱為“cpu demo thread”占用的cpu較高
dashboard
# 當前最忙的前N個線程 thread -b, ##找出當前阻塞其他線程的線程 thread -n 5 -i 1000 #間隔一定時間后展示,本例中可以看到最忙CPU線程為id=45,代碼行數(shù)為19
thread -n 5
# jad查看反編譯的代碼
jad cn.itxs.controller.CpuController
package cn.itxs.controller;
?
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.concurrent.TimeUnit;
?
@RestController
@RequestMapping("/thread")
public class ThreadController {
private Object obj1 = new Object();
private Object obj2 = new Object();
?
@RequestMapping("/test")
@ResponseBody
public String test(){
new Thread(() -> {
synchronized (obj1){
try {
TimeUnit.SECONDS.sleep(10);
} catch (InterruptedException e) {
}
synchronized (obj2){
System.out.println("thread 1執(zhí)行到此");
}
}
},"thread 1").start();
try {
TimeUnit.SECONDS.sleep(2);
} catch (InterruptedException e) {
e.printStackTrace();
}
new Thread(() -> {
synchronized (obj2) {
synchronized (obj1){
System.out.println("thread 2執(zhí)行到此");
}
}
},"thread 2").start();
return "thread test";
}
}
# 啟動SpringBoot演示程序,訪問頁面http://192.168.50.100:8080/thread/test
# 運行arthas,查看線程
thread
# 查看阻塞線程
thread -b
# jad反編譯查看代碼
jad --source-only cn.itxs.controller.ThreadController
準備一個有問題的java類
package cn.itxs.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.UUID;
import java.util.concurrent.TimeUnit;
@RestController
@RequestMapping("/hot")
public class HotController {
@RequestMapping("/test")
@ResponseBody
public String test(){
boolean flag = true;
if (flag) {
System.out.println("開始處理邏輯");
throw new RuntimeException("出異常了");
}
System.out.println("結束流程");
return "hot test";
}
}
啟動Spring Boot程序,訪問頁面http://192.168.50.94:8080/hot/test發(fā)現(xiàn)報錯,當我們分析到這段程序出異常后,我們分析異常后進行線上代碼修改不停機不重新發(fā)包的情況下的熱更新,操作流程如下:
# 第一步:`jad命令` 將需要更改的文件先進行反編譯,保存下來 ,編譯器修改,-c 指定這個類的classloader的哈希值,–source-only只顯示源碼,最后是文件反編譯之后的存放路徑
jad --source-only cn.itxs.controller.HotController > /home/commons/arthas/data/HotController.java
# 我們將HotController.java中的throw new RuntimeException("出異常了")代碼刪掉,修改完后需要將類重新加載到JVM
# 第二步:`SC命令` 查找當前類是哪個classLoader加載的,首先,使用sc命令找到要修改的類.sc全稱-search class, -d表示detail,主要是為了獲取classLoader的hash值
sc -d *HotController | grep classLoader
classLoaderHash 6267c3bb #類加載器 編號
# 第三步:`MC命令` 用指定的classloader重新將類在內存中編譯
mc -c 6267c3bb /home/commons/arthas/data/HotController.java -d /home/commons/arthas/class
# 第四步:`redefine命令` 將編譯后的類加載到JVM,參數(shù)是編譯后的.class文件地址
redefine /home/commons/arthas/class/cn/itxs/controller/HotController.class
以上操作后再次訪問一下頁面http://192.168.50.94:8080/hot/test,發(fā)現(xiàn)異常沒有了程序已經(jīng)是我們修改正確后的,class文件替換成功,功能確實很強大。
上面我們是手工一步步執(zhí)行,當然我們可以使用shell腳本串起來簡單操作。
此外還可以安裝Alibaba Cloud Toolkit熱部署組件(一鍵retransform),熱部署組件支持一鍵將編輯器中修改的 Java 源碼快速編譯,并更新到遠端應用服務中,免去手動 dump、mc 的過程。此外,也可以一鍵還原 retransform 的類文件。
由于Arthas命令還是較復雜,Arthas-idea插件(部分命令可視化)是一個幫助生成命令的IDEA插件,使用文檔:https://www.yuque.com/arthas-idea-plugin;
安裝基于Arthas實現(xiàn)的簡單好用的熱部署插件ArthasHotSwap可以一鍵生成熱部署命令,提高我們線上維護的效率。
package cn.itxs.controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import org.springframework.web.bind.annotation.RestController;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
@RestController
@RequestMapping("/watch")
public class WatchController {
private static Random random = new Random();
private int illegalArgumentCount = 0;
@RequestMapping("/test")
@ResponseBody
public String test(){
String res = null;
try {
int number = random.nextInt() / 10000;
List<Integer> idStrs = this.getIdStr(number);
res = printList(number, idStrs);
}
catch (Exception e) {
System.out.println(String.format("illegalArgumentCount:%3d, ", this.illegalArgumentCount) + e.getMessage());
}
return res;
}
private List<Integer> getIdStr(int number) {
if (number < 5) {
++this.illegalArgumentCount;
throw new IllegalArgumentException("number is: " + number + ", need >= 5");
}
ArrayList<Integer> result = new ArrayList<Integer>();
int count = 2;
while (count <= number) {
if (number % count == 0) {
result.add(count);
number /= count;
count = 2;
continue;
}
++count;
}
return result;
}
private String printList(int number, List<Integer> primeFactors) {
StringBuffer sb = new StringBuffer(number + "=");
for (int factor : primeFactors) {
sb.append(factor).append('*');
}
if (sb.charAt(sb.length() - 1) == '*') {
sb.deleteCharAt(sb.length() - 1);
}
System.out.println(sb);
return sb.toString();
}
}
啟動Spring Boot程序,通過Jmeter每秒訪問一次http://192.168.50.100:8080/watch/test
# Arthas中的**watch**命令可以讓我們能方便的觀察到指定方法的調用情況,可以觀察到返回值,入?yún)ⅲ约白兞康取?# watch 全路徑類名 方法名 觀察表達式 -x 3 ,觀察表達式匹配ognl表達式,觀察的維度也比較多。
# 比如:watch cn.itxs.controller.WatchController printList "{params,returnObj}" -x 3
# 查看printList方法的入?yún)⒑统鰠ⅲ?x表示的是遍歷結果深度默認1,只會打印對象的堆地址,看不到具體的屬性值,-x 2會打印結果的屬性值的信息 -x 3會輸出入?yún)傩灾岛徒Y果屬性值
# -n 1只抓緊一次,由于我們這里是模擬一直請求的
watch cn.itxs.controller.WatchController printList '{params}' -n 1
# -x 表示的是遍歷結果深度默認3
watch cn.itxs.controller.WatchController printList '{params}' -n 1 -x 3
# params[0]代表第一個參數(shù)
watch cn.itxs.controller.WatchController printList '{params[0]}' -n 1 -x 3
# 方法的返回值
watch cn.itxs.controller.WatchController getIdStr '{returnObj}' -n 1 -x 3
# 方法參數(shù)和返回值
watch cn.itxs.controller.WatchController getIdStr '{params,returnObj}' -n 1 -x 3
# 觀察方法執(zhí)行前后當前對象屬性值
watch cn.itxs.controller.WatchController getIdStr 'target.illegalArgumentCount'
# 觀察異常信息,觀察表達式里增加throwExp就好了。如果增加-e 參數(shù)就能過濾掉非異常的監(jiān)聽了。
# 在觀察表達式后面,我們可以增加條件表達式,例如按時間過濾:#cost>0.5,單位是毫秒,那么控制臺輸出來的都是耗時在0.5毫秒以上的方法調用
watch cn.itxs.controller.WatchController getIdStr '{params}' '#cost>0.5'
# 按條件過濾觀察params[1].size>4:這里支持ognl表達式。下面例子的意思是:第二個參數(shù)(也就是List primeFactors),的size大于4的時候才觀察入?yún)ⅰ?watch cn.itxs.controller.WatchController printList '{params}' 'params[1].size>4' -x 3
monitor結果包括如下
# -c :統(tǒng)計周期,默認值為10秒
monitor -c 10 cn.itxs.controller.WatchController getIdStr
# 在方法調用之前計算condition-express,方法后可帶表達式
monitor -b -c 10 cn.itxs.controller.WatchController getIdStr
# trace:方法內部調用路徑,并輸出方法路徑上的每個節(jié)點上耗時
trace cn.itxs.controller.WatchController test -n 2
#包含jdk的函數(shù)--skipJDKMethod <value> skip jdk method trace, default value true.默認情況下,trace不會包含jdk里的函數(shù)調用,如果希望trace jdk里的函數(shù),需要顯式設置--skipJDKMethod false。
trace --skipJDKMethod false cn.itxs.controller.WatchController test -n 2
# 調用耗時過濾,只會展示耗時大于10ms的調用路徑,有助于在排查問題的時候,只關注異常情況
trace cn.itxs.controller.WatchController test '#cost > 1'
# 輸出當前方法被調用的調用路徑,getIdStr是從test方法調用進來的
stack cn.itxs.controller.WatchController getIdStr -n 1
# 輸出當前方法被調用的調用路徑,條件表達過濾,第0個參數(shù)小于0,也可以根據(jù)執(zhí)行時間來過濾,'#cost>1'
stack cn.itxs.controller.WatchController getIdStr 'params[0]<0' -n 1
tt(TimeTunnel):方法執(zhí)行數(shù)據(jù)的時空隧道,記錄下指定方法每次調用的入?yún)⒑头祷匦畔ⅲ⒛軐@些不同的時間下調用進行觀測。對于一個最基本的使用來說,就是記錄下當前方法的每次調用環(huán)境現(xiàn)場。
# 記錄指定方法的每次調用環(huán)境現(xiàn)場
tt -t cn.itxs.controller.WatchController getIdStr
# 列出所有調用記錄
tt -l cn.itxs.controller.WatchController getIdStr
# 篩選調用記錄
tt -s 'method.name=="getIdStr"'
# 查看調用信息
tt -i 1001
# 重新發(fā)起一次調用
tt -i 1001 -p
# 啟動時指定Linux的ip
java -jar arthas-boot.jar --target-ip 192.168.50.94
profiler** 命令支持生成應用熱點的火焰圖。本質上是通過不斷的采樣,然后把收集到的采樣結果生成火焰圖。一般分析性能可以先通過Arthas profiler命令生成**jfr文件;在本地通過 jprofiler來分析 jfr文件,定位誰在調用我。
# 啟動profiler 默認情況下,生成的是cpu的火焰圖,即event為cpu。可以用--event參數(shù)來指定
profiler start
# 獲取已采集的sample的數(shù)量
profiler getSamples
# 查看profiler狀態(tài)
profiler status
# 停止profiler 生成html格式結果,默認情況下,結果文件是html格式,也可以用--format參數(shù)指定;或者在--file參數(shù)里用文件名指名格式。比如--file /tmp/result.html
profiler stop --format html
通過瀏覽器查看arthas-output下面的profiler結果,http://192.168.50.100:3658/arthas-output/
# profiler支持的events
profiler list
# 可以用--event參數(shù)指定要采樣的事件,比如對alloc事件進入采樣:
profiler start --event alloc
# 使用execute來執(zhí)行復雜的命令
profiler execute 'start,framebuf=5000000'
# 生成 jfr格式結果;注意,jfr只支持在 start時配置。如果是在stop時指定,則不會生效。
profiler start --file /tmp/test.jfr
# 配置 include/exclude 來過濾數(shù)據(jù)
profiler start --include 'java/*' --include 'demo/*' --exclude '*Unsafe.park*'
# profiler執(zhí)行 300 秒自動結束,可以用 -d/--duration 參數(shù)指定
profiler start --duration 300
{
"action": "exec",
"requestId": "req112",
"sessionId": "94766d3c-8b39-42d3-8596-98aee3ccbefb",
"consumerId": "955dbd1325334a84972b0f3ac19de4f7_2",
"command": "version",
"execTimeout": "10000"
}
<dependency>
<groupId>com.taobao.arthas</groupId>
<artifactId>arthas-agent-attach</artifactId>
<version>${arthas.version}</version>
</dependency>
<dependency>
<groupId>com.taobao.arthas</groupId>
<artifactId>arthas-packaging</artifactId>
<version>${arthas.version}</version>
</dependency>
import com.taobao.arthas.agent.attach.ArthasAgent;
public class ArthasAttachExample {
public static void main(String[] args) {
ArthasAgent.attach();
}
}
原文來自IT小神博客 http://www.itxiaoshen.cn
在SpringBoot2應用中加入arthas-spring-boot-starter后,Spring會啟動arthas服務,并且進行attach自身進程,并配合tunnel server實現(xiàn)遠程管理。這樣的方案非常適合在微服務容器環(huán)境中進行遠程診斷,在容器網(wǎng)絡環(huán)境中僅需要對外暴露tunnel server的端口。
在容器化部署的環(huán)境內部,Java進程可以是在不同的機器啟動的,想要使用Arthas去診斷會比較麻煩,因為用戶通常沒有機器的權限,即使登陸機器也分不清是哪個Java進程。在這種情況下,可以使用 Arthas Tunnel Server/Client。
整個Arthas的功能體系中,可以通過Arthas Tunnel Server/Client來遠程管理/連接多個Agent(也就代表著可以監(jiān)控多個JVM進程)。主要目的用于監(jiān)控和獲取目標的JVM的進程數(shù)據(jù)信息。
下載地址Arthas tunnel server,目前最新版本為arthas-all-3.6.7版本,如下圖所示。
針對于Arthas的安裝包進行下載資料進行介紹:
阿里云的下載地址:arthas.aliyun.com/download/ar…
Arthas tunnel server是一個Spring boot fat jar 應用,直接java -jar啟動:
java -jar arthas-tunnel-server.jar
復制代碼
默認情況下,arthas tunnel server的web端口是8080,Arthas agent 連接的端口是7777
打開WebConsole,分別輸入Arthas agent的ip(127.0.0.1)和port(7777),和SpringBoot應用里配置的agent-id(URJZ5L48RPBR2ALI5K4V),點Connect即可。
如果希望可以通過瀏覽器連接Arthas服務,此時這里的Arthas服務指的不是Arthas tunnel server,Arthas是總體的服務控制端,發(fā)送指令的部分,而Arthas tunnel server屬于對接和管理agent的專門服務(依賴于Arthas Spring Boot Starter的服務)。
出了CLI模式之外,Arthas目前支持 Web Console,用戶在attach成功之后,可以直接訪問:http://127.0.0.1:8563/。 可以填入 IP,遠程連接其它機器上的arthas。啟動之后,可以訪問 http://127.0.0.1:8080/ ,再通過agentId連接到已注冊的arthas agent 上,如下圖所示。
通過Spring Boot的Endpoint,可以查看到具體的連接信息: http://127.0.0.1:8080/actuator/arthas ,
登陸用戶名是arthas,密碼在 arthas tunnel server 的日志里可以找到,比如:
注意:默認情況下,arthas 只 listen 127.0.0.1,所以如果想從遠程連接,則可以使用 --target-ip參數(shù)指定 listen 的 IP,更多參考-h的幫助說明。 注意會有安全風險,考慮下面的 tunnel server 的方案。
主要有兩種模式連接Arthas tunnel server:
在啟動 arthas,可以傳遞--tunnel-server參數(shù),比如:
as.sh --tunnel-server 'ws://127.0.0.1:7777/ws'
復制代碼
如果有特殊需求,可以通過--agent-id參數(shù)里指定 agentId。默認情況下,會生成隨機 ID。attach 成功之后,會打印出 agentId。
,---. ,------. ,--------.,--. ,--. ,---. ,---.
/ O \ | .--. ''--. .--'| '--' | / O \ ' .-'
| .-. || '--'.' | | | .--. || .-. |`. `-.
| | | || |\ \ | | | | | || | | |.-' |
`--' `--'`--' '--' `--' `--' `--'`--' `--'`-----'
wiki https://arthas.aliyun.com/doc
tutorials https://arthas.aliyun.com/doc/arthas-tutorials.html
version 3.1.2
pid 86183
time 2022-11-30 15:40:53
id URJZ5L48RPBR2ALI5K4V
復制代碼
即使是啟動時沒有連接到 tunnel server,也可以在后續(xù)自動重連成功之后,通過 session 命令來獲取 agentId:
[arthas@86183]$ session
Name Value
-----------------------------------------------------
JAVA_PID 86183
SESSION_ID f7273eb5-e7b0-4a00-bc5b-3fe55d741882
AGENT_ID URJZ5L48RPBR2ALI5K4V
TUNNEL_SERVER ws://127.0.0.1:7777/ws
復制代碼
在瀏覽器里訪問 http://localhost:8080/arthas,輸入agentId,就可以連接到本機/其他機器上上的 arthas 了。
as.sh --tunnel-server 'ws://127.0.0.1:7777/ws' --app-name demoapp ,則生成的 agentId 可能是demoapp_URJZ5L48RPBR2ALI5K4V。
復制代碼
Tunnel server 會以_做分隔符,提取出appName,方便按應用進行管理。
解壓的 arthas 目錄下的 arthas.properties,或者在 spring boot 應用的application.properties里配置appName。
只支持 springboot2
arthas.version:3.6.7
<dependency>
<groupId>com.taobao.arthas</groupId>
<artifactId>arthas-spring-boot-starter</artifactId>
<version>${arthas.version}</version>
</dependency>
復制代碼
應用啟動后,spring 會啟動 arthas,并且 attach 自身進程。如果你不知道如何創(chuàng)建或者引入哪些依賴,可以采用一鍵創(chuàng)建包含 Arthas Spring Boot Starter 的工程:點擊跳轉到云原生腳手架
可以看到最下面已經(jīng)自動勾選了arthas的監(jiān)控機制體系。
arthas:
agent-name: nihaotest
agent-id: URJZ5L48RPBR2ALI5K4V #需手工指定agent-id
tunnel-server: ws://127.0.0.1:7777/ws
復制代碼
需要配置 spring boot 暴露 endpoint:假定endpoint 端口是 8080,則通過下面 url 可以查看:
http://localhost:8080/actuator/arthas
{
"arthasConfigMap": {
"agent-id": "hsehdfsfghhwertyfad",
"tunnel-server": "ws://47.75.156.201:7777/ws",
}
}
復制代碼
最后,啟動SpringBoot服務即可。
非 Spring Boot 應用,可以通過下面的方式來使用:
<dependency>
<groupId>com.taobao.arthas</groupId>
<artifactId>arthas-agent-attach</artifactId>
<version>${arthas.version}</version>
</dependency>
<dependency>
<groupId>com.taobao.arthas</groupId>
<artifactId>arthas-packaging</artifactId>
<version>${arthas.version}</version>
</dependency>
復制代碼
import com.taobao.arthas.agent.attach.ArthasAgent;
public class ArthasAttachExample {
public static void main(String[] args) {
ArthasAgent.attach();
}
}
復制代碼
也可以配置屬性:
HashMap<String, String> configMap = new HashMap<String, String>();
configMap.put("arthas.appName", "demo");
configMap.put("arthas.tunnelServer", "ws://127.0.0.1:7777/ws");
ArthasAgent.attach(configMap);
復制代碼
需要在 spring boot 的application.properties里配置 arthas.enable-detail-pages=true
注意,開放管理頁面有風險!管理頁面沒有安全攔截功能,務必自行增加安全措施。
在本地啟動 tunnel-server,然后使用as.sh attach,并且指定應用名--app-name test:
$ as.sh --tunnel-server 'ws://127.0.0.1:7777/ws' --app-name test
telnet connecting to arthas server... current timestamp is 1627539688
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
,---. ,------. ,--------.,--. ,--. ,---. ,---.
/ O \ | .--. ''--. .--'| '--' | / O \ ' .-'
| .-. || '--'.' | | | .--. || .-. |`. `-.
| | | || |\ \ | | | | | || | | |.-' |
`--' `--'`--' '--' `--' `--' `--'`--' `--'`-----'
wiki https://arthas.aliyun.com/doc
tutorials https://arthas.aliyun.com/doc/arthas-tutorials.html
version 3.5.3
main_class demo.MathGame
pid 65825
time 2022-07-29 14:21:29
id test_PE3LZO9NA9ENJYTPGL9L
復制代碼
然后訪問 tunnel-server,可以看到所有連接的應用列表:
http://localhost:8080/apps.html
復制代碼
再打開詳情,則可以看到連接的所有 agent 列表:
http://localhost:8080/agents.html?app=test
復制代碼
鏈接:https://juejin.cn/post/7213744681393176633
*請認真填寫需求信息,我們會在24小時內與您取得聯(lián)系。