精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

實(shí)戰(zhàn)Arthas:常見(jiàn)命令與優(yōu)秀實(shí)踐

開(kāi)發(fā) 前端
本文將介紹 Arthas 的常用命令和使用技巧,幫助您更好地利用該工具進(jìn)行故障排查和性能優(yōu)化。

當(dāng)涉及到 Java 應(yīng)用程序的診斷和調(diào)優(yōu)時(shí),Arthas 是一款備受推崇的開(kāi)源工具,無(wú)論是線(xiàn)上問(wèn)題的定位,還是實(shí)時(shí)性能監(jiān)控和分析,Arthas 都能為您提供強(qiáng)大的支持。

本文將介紹 Arthas 的常用命令和使用技巧,幫助您更好地利用該工具進(jìn)行故障排查和性能優(yōu)化。

一、前言

在開(kāi)始本文之前,先推薦兩個(gè)東西:

一個(gè)是 Arthas 官網(wǎng):https://arthas.aliyun.com/doc/,官方文檔對(duì) Arthas 的每個(gè)命令都做出了介紹和解釋?zhuān)⑶疫€有在線(xiàn)教程,方便大家學(xué)習(xí)和熟悉命令。

另外還有一個(gè)向大家推薦的是一款名為 Arthas Idea 的 IDEA 插件。

這是一款能快速生成 Arthas命令的插件,可快速生成可用于該類(lèi)或該方法的 Arthas 命令,大大提高排查問(wèn)題的效率。

二、常用命令

盡管 Arthas 命令眾多,但在實(shí)際使用中我們只需聚焦于那些常用命令。本文旨在重點(diǎn)介紹這些常用命令,并提供使用技巧和最佳實(shí)踐,幫助您更好地運(yùn)用 Arthas。

1.類(lèi)命令

(1) getstatic

查看類(lèi)的靜態(tài)屬性。推薦直接使用 ognl 命令,更加靈活。

# getstatic class_name field_name
getstatic demo.MathGame random

# 如果該靜態(tài)屬性是一個(gè)復(fù)雜對(duì)象,還可以支持在該屬性上通過(guò) ognl 表達(dá)式進(jìn)行遍歷,過(guò)濾,訪(fǎng)問(wèn)對(duì)象的內(nèi)部屬性等操作。
# 例如,假設(shè) n 是一個(gè) Map,Map 的 Key 是一個(gè) Enum,我們想過(guò)濾出 Map 中 Key 為某個(gè) Enum 的值,可以寫(xiě)如下命令
getstatic com.alibaba.arthas.Test n 'entrySet().iterator.{? #this.key.name()=="STOP"}'

(2) jad

反編譯指定已加載類(lèi)的源碼。jad 只能反編譯單個(gè)類(lèi),如需批量下載指定包的目錄的 class 字節(jié)碼請(qǐng)使用 dump 命令。

比如我們想知道自己提交的代碼是否生效了,這種場(chǎng)景jad 命令就特別有用。

# 反編譯 java.lang.String
jad java.lang.String
# 默認(rèn)情況下,反編譯結(jié)果里會(huì)帶有 ClassLoader 信息,通過(guò) --source-only 選項(xiàng),可以只打印源代碼。方便和 mc/retransform 命令結(jié)合使用。
jad --source-only java.lang.String
# 反編譯指定的函數(shù)
jad java.lang.String substring
# 當(dāng)有多個(gè) ClassLoader 都加載了這個(gè)類(lèi)時(shí),jad 命令會(huì)輸出對(duì)應(yīng) ClassLoader 實(shí)例的 hashcode
# 然后你只需要重新執(zhí)行 jad 命令,并使用參數(shù) -c <hashcode> 就可以反編譯指定 ClassLoader 加載的那個(gè)類(lèi)了
jad org.apache.log4j.Logger -c 69dcaba4

(3) retransform

加載外部的 .class 文件,retransform jvm 已加載的類(lèi)。

# 結(jié)合 jad/mc 命令使用,jad 命令反編譯,然后可以用其它編譯器,比如 vim 來(lái)修改源碼
jad --source-only com.example.demo.arthas.user.UserController > /tmp/UserController.java
# mc 命令來(lái)內(nèi)存編譯修改過(guò)的代碼
mc /tmp/UserController.java -d /tmp
# 用 retransform 命令加載新的字節(jié)碼
retransform /tmp/com/example/demo/arthas/user/UserController.class

加載指定的 .class 文件,然后解析出 class name,再 retransform jvm 中已加載的對(duì)應(yīng)的類(lèi)。每加載一個(gè) .class 文件,則會(huì)記錄一個(gè) retransform entry。

如果多次執(zhí)行 retransform 加載同一個(gè) class 文件,則會(huì)有多條 retransform entry。

# 查看 retransform entry
retransform -l
# 刪除指定 retransform entry,需要指定 id:
retransform -d 1
# 刪除所有 retransform entry
retransform --deleteAll
# 顯式觸發(fā) retransform
retransform --classPattern demo.MathGame

如果對(duì)某個(gè)類(lèi)執(zhí)行 retransform 之后,想消除 retransform 的影響,則需要:

  • 刪除這個(gè)類(lèi)對(duì)應(yīng)的 retransform entry。
  • 重新顯式觸發(fā) retransform。

retransform 的限制:

  • 不允許新增加 field/method。
  • 正在跑的函數(shù),沒(méi)有退出不能生效。

使用 mc 命令來(lái)編譯 jad 的反編譯的代碼有可能失敗。可以在本地修改代碼,編譯好后再上傳到服務(wù)器上。有的服務(wù)器不允許直接上傳文件,可以使用 base64 命令來(lái)繞過(guò)。

  • 在本地先轉(zhuǎn)換 .class 文件為 base64,再保存為 result.txt。
base64  -i /tmp/test.class -o /tmp/result.txt
  • 到服務(wù)器上,新建并編輯 result.txt,復(fù)制本地的內(nèi)容,粘貼再保存。
vim  /tmp/result.txt
  • 把服務(wù)器上的 result.txt 還原為.class。
base64 -d /tmp/result.txt > /tmp/test.class
  • 用 md5 命令計(jì)算哈希值,校驗(yàn)是否一致。
md5sum  /tmp/test.class

2.監(jiān)測(cè)排查命令

監(jiān)測(cè)排查命令是 Arthas 中最常用的命令。

請(qǐng)注意,這些命令,都通過(guò)字節(jié)碼增強(qiáng)技術(shù)來(lái)實(shí)現(xiàn)的,會(huì)在指定類(lèi)的方法中插入一些切面來(lái)實(shí)現(xiàn)數(shù)據(jù)統(tǒng)計(jì)和觀(guān)測(cè),因此在線(xiàn)上、預(yù)發(fā)使用時(shí),請(qǐng)盡量明確需要觀(guān)測(cè)的類(lèi)、方法以及條件,診斷結(jié)束要執(zhí)行 stop 或?qū)⒃鰪?qiáng)過(guò)的類(lèi)執(zhí)行 reset 命令。

(1) monitor

方法執(zhí)行監(jiān)控。可對(duì)方法的調(diào)用次數(shù),成功次數(shù),失敗次數(shù)等維度進(jìn)行統(tǒng)計(jì)。

# -b:計(jì)算條件表達(dá)式過(guò)濾統(tǒng)計(jì)結(jié)果(方法執(zhí)行完畢之前),默認(rèn)是方法執(zhí)行之后過(guò)濾
# -c:統(tǒng)計(jì)周期,默認(rèn)值為 120 秒
# params[0] <= 2:過(guò)濾條件,方法第一個(gè)參數(shù)小于等于2
monitor -b -c 5 com.test.testes.MathGame primeFactors "params[0] <= 2"

(2) stack

輸出當(dāng)前方法被調(diào)用的調(diào)用路徑。

很多時(shí)候我們都知道一個(gè)方法被執(zhí)行,但這個(gè)方法被執(zhí)行的路徑非常多,或者你根本就不知道這個(gè)方法是從那里被執(zhí)行了,此時(shí)你需要的是 stack 命令。

# -n:執(zhí)行次數(shù)
stack demo.MathGame primeFactors  -n  2

(3) thread

查看當(dāng)前線(xiàn)程信息,查看線(xiàn)程的堆棧。

# 沒(méi)有參數(shù)時(shí),默認(rèn)按照 CPU 增量時(shí)間降序排列,只顯示第一頁(yè)數(shù)據(jù)
# -i 1000: 統(tǒng)計(jì)最近 1000ms 內(nèi)的線(xiàn)程 CPU 時(shí)間
# -n 3: 展示當(dāng)前最忙的前 N 個(gè)線(xiàn)程并打印堆棧
# --state WAITING:查看指定狀態(tài)的線(xiàn)程
thread

# 顯示指定線(xiàn)程的運(yùn)行堆棧
thread id

# 找出當(dāng)前阻塞其他線(xiàn)程的線(xiàn)程,注意,目前只支持找出 synchronized 關(guān)鍵字阻塞住的線(xiàn)程, 如果是 java.util.concurrent.Lock 目前還不支持。
thread -b

輸出:

  • Internal 表示為 JVM 內(nèi)部線(xiàn)程,參考 dashboard 命令的介紹。
  • cpuUsage 為采樣間隔時(shí)間內(nèi)線(xiàn)程的 CPU 使用率,與 dashboard 命令的數(shù)據(jù)一致。
  • deltaTime 為采樣間隔時(shí)間內(nèi)線(xiàn)程的增量 CPU 時(shí)間,小于 1ms 時(shí)被取整顯示為 0ms。
  • time 為線(xiàn)程運(yùn)行總 CPU 時(shí)間。

(4) trace

方法內(nèi)部調(diào)用路徑,并輸出方法路徑上的每個(gè)節(jié)點(diǎn)上耗時(shí)。

trace 命令在定位性能問(wèn)題的時(shí)候特別有用。

# -n 1:限制匹配次數(shù)
# --skipJDKMethod false:默認(rèn)情況下,trace 不會(huì)包含 jdk 里的函數(shù)調(diào)用,如果希望 trace jdk 里的函數(shù),需要顯式設(shè)置
# --exclude-class-pattern :排除掉指定的類(lèi)
trace javax.servlet.Filter * -n 1 --skipJDKMethod false --exclude-class-pattern com.demo.TestFilter
# 正則表達(dá)式匹配路徑上的多個(gè)類(lèi)和函數(shù),達(dá)到多層 trace 的效果
trace -E com.test.ClassA|org.test.ClassB method1|method2|method3

動(dòng)態(tài) tradce參考:https://arthas.aliyun.com/doc/trace.html#動(dòng)態(tài)-trace

(5) tt

方法執(zhí)行數(shù)據(jù)的時(shí)空隧道,記錄下指定方法每次調(diào)用的入?yún)⒑头祷匦畔ⅲ⒛軐?duì)這些不同的時(shí)間下調(diào)用進(jìn)行觀(guān)測(cè)。

說(shuō)明:

  • tt 命令的實(shí)現(xiàn)是:把函數(shù)的入?yún)?返回值等,保存到一個(gè)Map<Integer, TimeFragment>里,默認(rèn)的大小是 100。
  • tt 相關(guān)功能在使用完之后,需要手動(dòng)釋放內(nèi)存,否則長(zhǎng)時(shí)間可能導(dǎo)致 OOM。退出 arthas 不會(huì)自動(dòng)清除 tt 的緩存 map。
  • 需要強(qiáng)調(diào)的是,tt 命令是將當(dāng)前環(huán)境的對(duì)象引用保存起來(lái),但僅僅也只能保存一個(gè)引用而已。如果方法內(nèi)部對(duì)入?yún)⑦M(jìn)行了變更,或者返回的對(duì)象經(jīng)過(guò)了后續(xù)的處理,那么在  tt  查看的時(shí)候?qū)o(wú)法看到當(dāng)時(shí)最準(zhǔn)確的值。這也是為什么 watch 命令存在的意義。
# -l:顯示tt記錄
tt -l

# -s:檢索tt記錄,比如:-s 'method.name=="primeFactors"'
tt -s 'method.name=="primeFactors"'

# -t:這個(gè)參數(shù)的表明希望記錄下類(lèi) *Test 的 print 方法的每次執(zhí)行情況。
tt -t

# 查看具體調(diào)用信息
tt -i 1003

# -w:--watch-express 觀(guān)察時(shí)空隧道使用 ognl 表達(dá)式
tt -w '@demo.MathGame@random.nextInt(100)'

# 重做一次調(diào)用,當(dāng)我們對(duì)程序做出了修改之后,希望再次調(diào)用觀(guān)測(cè)結(jié)果,此時(shí)你需要 -p 參數(shù)
# --replay-times:指定調(diào)用次數(shù)
# --replay-interval:指定多次調(diào)用間隔(單位 ms, 默認(rèn) 1000ms)
tt -i 1004 -p

# 通過(guò)索引刪除指定的 tt 記錄
tt -d 1001

# 清除所有的 tt 記錄
tt --delete-all

Spring MVC里獲取對(duì)于的 bean:

# 獲取Spring Context里的bean
tt -n 1 -t org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter invokeHandlerMethod
tt -i 1000 -w 'target.getApplicationContext().getBean("helloWorldService").getHelloMessage()'

(6) watch

函數(shù)執(zhí)行數(shù)據(jù)觀(guān)測(cè),通過(guò)編寫(xiě) OGNL 表達(dá)式進(jìn)行對(duì)應(yīng)變量的查看。

  • watch 命令定義了 4 個(gè)觀(guān)察事件點(diǎn),即 -b 函數(shù)調(diào)用前,-e 函數(shù)異常后,-s 函數(shù)返回后,-f 函數(shù)結(jié)束后。
  • 4 個(gè)觀(guān)察事件點(diǎn) -b、-e、-s 默認(rèn)關(guān)閉,-f 默認(rèn)打開(kāi),當(dāng)指定觀(guān)察點(diǎn)被打開(kāi)后,在相應(yīng)事件點(diǎn)會(huì)對(duì)觀(guān)察表達(dá)式進(jìn)行求值并輸出。
  • 這里要注意函數(shù)入?yún)⒑秃瘮?shù)出參的區(qū)別,有可能在中間被修改導(dǎo)致前后不一致,除了 -b 事件點(diǎn) params 代表函數(shù)入?yún)⑼猓溆嗍录即砗瘮?shù)出參。
  • 當(dāng)使用 -b 時(shí),由于觀(guān)察事件點(diǎn)是在函數(shù)調(diào)用前,此時(shí)返回值或異常均不存在。
  • 在 watch 命令的結(jié)果里,會(huì)打印出location信息。location有三種可能值:AtEnter,AtExit,AtExceptionExit。對(duì)應(yīng)函數(shù)入口,函數(shù)正常 return,函數(shù)拋出異常。
# -x表示遍歷深度,可以調(diào)整來(lái)打印具體的參數(shù)和結(jié)果內(nèi)容,默認(rèn)值是 1。
 # -x最大值是 4,防止展開(kāi)結(jié)果占用太多內(nèi)存。用戶(hù)可以在ognl表達(dá)式里指定更具體的 field。
 watch demo.MathGame primeFactors -x 3
 
 # 可以使用ognl表達(dá)式進(jìn)行條件過(guò)濾
 watch demo.MathGame primeFactors "{params[0],target}" "params[0]<0" "#cost>200"
 
 # 可以使用 target.field_name 訪(fǎng)問(wèn)當(dāng)前對(duì)象的某個(gè)屬性
 watch demo.MathGame primeFactors 'target.illegalArgumentCount'
 
 #  watch 構(gòu)造函數(shù)
 watch demo.MathGame <init> '{params,returnObj,throwExp}' -v
 
 # watch內(nèi)部類(lèi)
 watch OuterClass$InnerClass

3.JVM命令

(1) heapdump

生成堆轉(zhuǎn)儲(chǔ)文件。

# dump 到指定文件
heapdump arthas-output/dump.hprof
# 只 dump live 對(duì)象
heapdump --live /tmp/dump.hprof

(2) jfr

Java Flight Recorder (JFR) 是一種用于收集有關(guān)正在運(yùn)行的 Java 應(yīng)用程序的診斷和分析數(shù)據(jù)的工具。

它集成到 Java 虛擬機(jī) (JVM) 中,幾乎不會(huì)造成性能開(kāi)銷(xiāo),因此即使在負(fù)載較重的生產(chǎn)環(huán)境中也可以使用。

# 啟動(dòng) JFR 記錄
jfr start

# 啟動(dòng) jfr 記錄,指定記錄名,記錄持續(xù)時(shí)間,記錄文件保存路徑。
# --duration  JFR 記錄持續(xù)時(shí)間,支持單位配置,60s, 2m, 5h, 3d,不帶單位就是秒,默認(rèn)一直記錄。
jfr start -n myRecording --duration 60s -f /tmp/myRecording.jfr

# 查看所有 JFR 記錄信息
jfr status

# 查看指定記錄 id 的記錄信息
jfr status -r 1

# 查看指定狀態(tài)的記錄信息
jfr status --state closed

# jfr dump 會(huì)輸出從開(kāi)始到運(yùn)行該命令這段時(shí)間內(nèi)的記錄到 JFR 文件,且不會(huì)停止 jfr 的記錄
# 生成的結(jié)果可以用支持 jfr 格式的工具來(lái)查看。比如:JDK Mission Control : https://github.com/openjdk/jmc
jfr dump -r 1 -f /tmp/myRecording1.jfr

# 停止 jfr 記錄
jfr stop -r 1

(3) memory

查看 JVM 內(nèi)存信息。

輸出如下:

Memory                           used      total      max        usage
heap                             32M       256M       4096M      0.79%
g1_eden_space                    11M       68M        -1         16.18%
g1_old_gen                       17M       184M       4096M      0.43%
g1_survivor_space                4M        4M         -1         100.00%
nonheap                          35M       39M        -1         89.55%
codeheap_'non-nmethods'          1M        2M         5M         20.53%
metaspace                        26M       27M        -1         96.88%
codeheap_'profiled_nmethods'     4M        4M         117M       3.57%
compressed_class_space           2M        3M         1024M      0.29%
codeheap_'non-profiled_nmethods' 685K      2496K      120032K    0.57%
mapped                           0K        0K         -          0.00%
direct                           48M       48M        -          100.00%

(4) dashboard

當(dāng)前系統(tǒng)的實(shí)時(shí)數(shù)據(jù)面板,按 ctrl+c 退出。

# i:刷新實(shí)時(shí)數(shù)據(jù)的時(shí)間間隔 (ms),默認(rèn) 5000m
# n:刷新實(shí)時(shí)數(shù)據(jù)的次數(shù)
dashboard -i 5000 -n 3

顯示 ID 為 -1 的是 JVM的內(nèi)部線(xiàn)程,JVM 內(nèi)部線(xiàn)程包括下面幾種:

  • JIT 編譯線(xiàn)程:如  C1 CompilerThread0, C2 CompilerThread0。
  • GC 線(xiàn)程:如 GC Thread0, G1 Young RemSet Sampling。
  • 其它內(nèi)部線(xiàn)程:如 VM Periodic Task Thread, VM Thread, Service Thread。

當(dāng) JVM 堆(heap)/元數(shù)據(jù)(metaspace) 空間不足或 OOM 時(shí), GC 線(xiàn)程的 CPU 占用率會(huì)明顯高于其他的線(xiàn)程。

(5) classloader

classloader 命令將 JVM 中所有的 classloader 的信息統(tǒng)計(jì)出來(lái),并可以展示繼承樹(shù),urls 等。

# 按類(lèi)加載類(lèi)型查看統(tǒng)計(jì)信息
classloader

# 按類(lèi)加載實(shí)例查看統(tǒng)計(jì)信息
classloader -l

# 查看 ClassLoader 的繼承樹(shù)
classloader -t

# 查看 URLClassLoader 實(shí)際的 urls,通過(guò) classloader -l 可以獲取到哈希值
classloader -c 3d4eac69

(6) logger

查看 logger 信息,更新 logger level。

# 查看所有 logger 信息
logger

# 查看指定名字的 logger 信息
logger -n org.springframework.web

# 更新 logger level
logger --name ROOT --level debug

(7) sc

查看 JVM 已加載的類(lèi)信息。

# 模糊搜索
sc demo.*

# 打印類(lèi)的詳細(xì)信息
sc -d demo.MathGame

# 打印出類(lèi)的 Field 信息
sc -d -f demo.MathGame

(8) mbean

查看 Mbean 的信息。

所謂 MBean 就是托管的Java對(duì)象,類(lèi)似于 JavaBeans 組件,遵循 JMX(Java Management Extensions,即Java管理擴(kuò)展) 規(guī)范中規(guī)定的設(shè)計(jì)模式。

MBean可以表示任何需要管理的資源。

# 列出所有 Mbean 的名稱(chēng)
mbean

# 查看 Mbean 的元信息
mbean -m java.lang:type=Threading

# 查看 mbean 屬性信息,mbean 的 name 支持通配符匹配 mbean java.lang:type=Th*
mbean java.lang:type=Threading

#通配符匹配特定的屬性字段
mbean java.lang:type=Threading *Count

# 實(shí)時(shí)監(jiān)控使用-i,使用-n命令執(zhí)行命令的次數(shù)(默認(rèn)為 100 次)
mbean -i 1000 -n 50 java.lang:type=Threading *Count

比如我們可以使用 mbean 命令來(lái)查看 Druid 連接池的屬性:

mbean com.alibaba.druid.pool:name=dataSource,type=DruidDataSource

(9) profiler

生成應(yīng)用熱點(diǎn)的火焰圖。本質(zhì)上是通過(guò)不斷的采樣,然后把收集到的采樣結(jié)果生成火焰圖。

# 啟動(dòng) profiler
# 生成的是 cpu 的火焰圖,即 event 為cpu。可以用--event參數(shù)來(lái)指定。
profiler start --event cpu

# 獲取已采集的 sample 的數(shù)量
profiler getSamples

# 查看 profiler 狀態(tài)
profiler status

# 停止 profiler,生成結(jié)果,結(jié)果文件是html格式,也可以用--format參數(shù)指定
profiler stop --format html

# 恢復(fù)采樣,start和resume的區(qū)別是:start是新開(kāi)始采樣,resume會(huì)保留上次stop時(shí)的數(shù)據(jù)。
profiler resume

# 配置 include/exclude 來(lái)過(guò)濾數(shù)據(jù)
profiler start --include 'java/*' --include 'demo/*' --exclude '*Unsafe.park*'

# 生成 jfr 格式結(jié)果
profiler start --file /tmp/test.jfr

(10) vmoption

查看,更新 VM 診斷相關(guān)的參數(shù)。

# 查看所有的 option
vmoption

# 查看指定的 option
vmoption PrintGC

# 更新指定的 option
vmoption PrintGC true

(11) vmtool

vmtool  利用 JVMTI 接口,實(shí)現(xiàn)查詢(xún)內(nèi)存對(duì)象,強(qiáng)制 GC 等功能。

# --limit:可以限制返回值數(shù)量,避免獲取超大數(shù)據(jù)時(shí)對(duì) JVM 造成壓力。默認(rèn)值是 10
# --action:執(zhí)行的動(dòng)作
vmtool --action getInstances --className java.lang.String --limit 10

#強(qiáng)制 GC
vmtool --action forceGc

# interrupt 指定線(xiàn)程
vmtool --action interruptThread -t 1

4.特殊命令

可以使用 -v  查看觀(guān)察匹配表達(dá)式的執(zhí)行結(jié)果

(1) ognl

執(zhí)行 ognl 表達(dá)式,是Arthas中最為靈活的命令。

# -c:執(zhí)行表達(dá)式的 ClassLoader 的 hashcode,默認(rèn)值是 SystemClassLoader
# --classLoaderClass:指定執(zhí)行表達(dá)式的 ClassLoader 的 class name
# -x:結(jié)果對(duì)象的展開(kāi)層次,默認(rèn)值 1
ognl --classLoaderClass org.springframework.boot.loader.LaunchedURLClassLoader @org.springframework.boot.SpringApplication@logger

有關(guān) ognl 語(yǔ)法介紹,放在下文。

(2) options

全局開(kāi)關(guān),慎用!

# 查看所有的 options
options

# 設(shè)置指定的 option,默認(rèn)情況下json-format為 false,如果希望watch/tt等命令結(jié)果以 json 格式輸出,則可以設(shè)置json-format為 true。
options json-format true

# 默認(rèn)情況下,watch/trace/tt/trace/monitor等命令不支持java.* package 下的類(lèi)。可以設(shè)置unsafe為 true,則可以增強(qiáng)。
options unsafe true

# Arthas 默認(rèn)啟用strict模式,在ognl表達(dá)式里,禁止更新對(duì)象的 Property 或者調(diào)用setter函數(shù)
# 用戶(hù)如果確定要在ognl表達(dá)式里更新對(duì)象,可以執(zhí)行options strict false,關(guān)閉strict模式。
options strict false

5.幫助命令

(1) help

查看命令幫助信息,可以查看當(dāng)前 arthas 版本支持的指令,或者查看具體指令的使用說(shuō)明。

help dashboard 
或者
dashboard  -help

(2) history

打印命令歷史。

#查看最近執(zhí)行的3條指令
history 3

#清空指令
history -c

(3) cls

清空當(dāng)前屏幕區(qū)域。

(4) quit

僅退出當(dāng)前的連接,Attach 到目標(biāo)進(jìn)程上的 arthas 還會(huì)繼續(xù)運(yùn)行,端口會(huì)保持開(kāi)放,下次連接時(shí)可以直接連接上。或者直接按 Q 也能退出。

(5) stop

完全退出 arthas,stop 時(shí)會(huì)重置所有增強(qiáng)過(guò)的類(lèi)。

(6) reset

重置增強(qiáng)類(lèi),將被 Arthas 增強(qiáng)過(guò)的類(lèi)全部還原,Arthas 服務(wù)端 stop 時(shí)會(huì)重置所有增強(qiáng)過(guò)的類(lèi)。

# 還原指定類(lèi)
reset Test

# 還原所有類(lèi)
reset

6.Advice

無(wú)論是匹配表達(dá)式也好、觀(guān)察表達(dá)式也罷,他們核心判斷變量都是圍繞著一個(gè) Arthas 中的通用通知對(duì)象 Advice 進(jìn)行。

它的簡(jiǎn)略代碼結(jié)構(gòu)如下:

public class Advice {
    private final ClassLoader loader;
    private final Class<?> clazz;
    private final ArthasMethod method;
    private final Object target;
    private final Object[] params;
    private final Object returnObj;
    private final Throwable throwExp;
    private final boolean isBefore;
    private final boolean isThrow;
    private final boolean isReturn;

    // getter/setter
}

這里列一個(gè)表格來(lái)說(shuō)明不同變量的含義:

變量名

變量解釋

loader

本次調(diào)用類(lèi)所在的 ClassLoader

clazz

本次調(diào)用類(lèi)的 Class 引用

method

本次調(diào)用方法反射引用

target

本次調(diào)用類(lèi)的實(shí)例

params

本次調(diào)用參數(shù)列表,這是一個(gè)數(shù)組,如果方法是無(wú)參方法則為空數(shù)組

returnObj

本次調(diào)用返回的對(duì)象。當(dāng)且僅當(dāng) isReturn==true 成立時(shí)候有效,表明方法調(diào)用是以正常返回的方式結(jié)束。如果當(dāng)前方法無(wú)返回值 void,則值為 null

throwExp

本次調(diào)用拋出的異常。當(dāng)且僅當(dāng) isThrow==true 成立時(shí)有效,表明方法調(diào)用是以?huà)伋霎惓5姆绞浇Y(jié)束。

isBefore

輔助判斷標(biāo)記,當(dāng)前的通知節(jié)點(diǎn)有可能是在方法一開(kāi)始就通知,此時(shí) isBefore==true 成立,同時(shí) isThrow==false 和 isReturn==false,因?yàn)樵诜椒▌傞_(kāi)始時(shí),還無(wú)法確定方法調(diào)用將會(huì)如何結(jié)束。

isThrow

輔助判斷標(biāo)記,當(dāng)前的方法調(diào)用以?huà)伄惓5男问浇Y(jié)束。

isReturn

輔助判斷標(biāo)記,當(dāng)前的方法調(diào)用以正常返回的形式結(jié)束。

所有變量都可以在表達(dá)式中直接使用,如果在表達(dá)式中編寫(xiě)了不符合 OGNL 腳本語(yǔ)法或者引入了不在表格中的變量,則退出命令的執(zhí)行。

用戶(hù)可以根據(jù)當(dāng)前的異常信息修正 條件表達(dá)式 或 觀(guān)察表達(dá)式。

7.快捷鍵

# 自動(dòng)補(bǔ)全,命令后敲 - 或 -- ,然后按 tab 鍵,可以展示出此命令具體的選項(xiàng)
Tab

# 退出當(dāng)前連接
Q

# 后臺(tái)異步命令相關(guān)快捷鍵
ctrl + c: 終止當(dāng)前命令
ctrl + z: 掛起當(dāng)前命令,后續(xù)可以 bg/fg 重新支持此命令,或 kill 掉
ctrl + a: 回到行首
ctrl + e: 回到行尾

8.OGNL

OGNL(Object-Graph Navigation Language)是一種表達(dá)式語(yǔ)言(EL),簡(jiǎn)單來(lái)說(shuō)就是一種簡(jiǎn)化了的Java屬性的取值語(yǔ)言,Arthas使用它做表達(dá)式過(guò)濾。

OGNL 表達(dá)式官網(wǎng):https://commons.apache.org/dormant/commons-ognl/language-guide.htm

變量引用

OGNL支持用變量來(lái)保存中間結(jié)果,并在后面的代碼中再次引用它。

OGNL中的所有變量,對(duì)整個(gè)表達(dá)式都是全局可見(jiàn)的,引用變量的方法是在變量名之前加上 # 號(hào),OGNL會(huì)將當(dāng)前對(duì)象保存在 "this" 變量中,這個(gè)變量也可以像其他任何變量一樣引用,用 #this 表示當(dāng)前對(duì)象。

這里列舉一些常用的語(yǔ)法:

# 調(diào)用靜態(tài)屬性
'@全路徑類(lèi)目@靜態(tài)屬性名'

# 調(diào)用靜態(tài)方法
'@全路徑類(lèi)目@靜態(tài)方法名("參數(shù)")'

# 過(guò)濾,判斷,篩選
'params[0]':查看第一個(gè)參數(shù)
'params[0].size()':查看第一個(gè)參數(shù)的size
'params[0]=="xyz"':判斷字符串相等
'params[0]==123456789L':判斷l(xiāng)ong型
'params[0].{ #this.name }':將結(jié)果按name屬性映射
'params[0].{? #this.name == null }':按條件過(guò)濾
'params[0].{? #this.age > 10 }.size()':過(guò)濾后統(tǒng)計(jì)
'params[0].{^ #this.name != null}':選擇第一個(gè)滿(mǎn)足條件
'params[0].{$ #this.name != null}':選擇最后一個(gè)滿(mǎn)足條件
'params[0].{? #this.age > 10 }.size().(#this > 20 ? #this - 10 : #this + 10)':子表達(dá)式求值
'name in { null,"Untitled" }':這條語(yǔ)句判斷name是否等于null或者 Untitled


# 構(gòu)造對(duì)象
'#{ "foo" : "foo value", "bar" : "bar value" }':構(gòu)造map參數(shù)
'#@java.util.LinkedHashMap@{ "foo" : "foo value", "bar" : "bar value" }':構(gòu)造特定類(lèi)型map
'new com.Test("xiaoming",18)':構(gòu)造方法,new 全路徑類(lèi)名()
'new int[] { 1, 2, 3 }':創(chuàng)建數(shù)組并初始化


# 訪(fǎng)問(wèn)對(duì)象
'@com.Test@getPerson("xiaoming",18).name':訪(fǎng)問(wèn)復(fù)雜對(duì)象屬性,用 .屬性名 訪(fǎng)問(wèn)屬性
'@com.Test@getChilds({"xiaoming"})[0]':訪(fǎng)問(wèn)List或者數(shù)組類(lèi)型,用 [索引] 訪(fǎng)問(wèn)
'@com.Test@getMap()["xiaoming"]': 訪(fǎng)問(wèn)Map對(duì)象,用 ["key"],key要用雙引號(hào)

# 臨時(shí)變量
'#value1=@com.Test@getPerson("xiaoming",18), #value2=@com.Test@setPerson(#value1) ,{#value1,#value2}': 方法A的返回值當(dāng)做方法B的入?yún)?'#value1=@System@getProperty("java.home"), #value2=@System@getProperty("java.runtime.name"), {#value1, #value2}':執(zhí)行多行表達(dá)式,賦值給臨時(shí)變量,返回一個(gè)List
'#obj=new com.User("xiaoming",18),@com.Test@inputObj(#obj)':先用構(gòu)造函數(shù)構(gòu)造一個(gè)對(duì)象,然后把這個(gè)對(duì)象當(dāng)做入?yún)魅?/code>

9.實(shí)用功能

(1) 管道

Arthas 命令后可接 grep  進(jìn)行進(jìn)一步篩選或操作,比如:

classloader -a | grep "String"

(2) 后臺(tái)異步執(zhí)行

當(dāng)需要排查一個(gè)問(wèn)題,但是這個(gè)問(wèn)題的出現(xiàn)時(shí)間不能確定,那我們就可以把檢測(cè)命令掛在后臺(tái)運(yùn)行,并將保存到輸出日志。

# 比如希望執(zhí)行后臺(tái)執(zhí)行 trace 命令,那么調(diào)用下面命令
trace Test t &

# 如果希望查看當(dāng)前有哪些 arthas 任務(wù)在執(zhí)行,可以執(zhí)行 jobs 命令
jobs

# 可通過(guò) > 或者 >> 將任務(wù)輸出結(jié)果輸出到指定的文件中,可以和 & 一起使用,實(shí)現(xiàn) arthas 命令的后臺(tái)異步任務(wù)。比如:
trace Test t >> test.out &

#異步執(zhí)行的命令,如果希望停止,可執(zhí)行kill命令
kill <job-id>

# 當(dāng)任務(wù)正在前臺(tái)執(zhí)行,可以執(zhí)行 ‘ctrl + z’ 將任務(wù)暫停。通過(guò)jbos查看任務(wù)狀態(tài)將會(huì)變?yōu)?Stopped,再通過(guò)bg <job-id>或者fg <job-id>可讓任務(wù)重新開(kāi)始執(zhí)行
# 可以把對(duì)應(yīng)的任務(wù)轉(zhuǎn)到前臺(tái)繼續(xù)執(zhí)行。在前臺(tái)執(zhí)行時(shí),無(wú)法在 console 中執(zhí)行其他命令
fg <job-id>
# 可以把對(duì)應(yīng)的任務(wù)在后臺(tái)繼續(xù)執(zhí)行
bg <job-id>

10.實(shí)用技巧

#  獲取接口的響應(yīng)時(shí)間
watch org.springframework.web.servlet.DispatcherServlet doService '{params[0].getRequestURI()+" "+ #cost}'  -n 5  -x 3 '#cost>100'  -f

# 獲取指定header 頭的信息,比如這里 獲取 trace-id
 watch org.springframework.web.servlet.DispatcherServlet doService '{params[0].getRequestURI()+"  header="+params[1].getHeaders("trace-id")}'  -n 10  -x 3 -f
 
# 查看執(zhí)行的SQL,下面兩個(gè)都可以
watch java.sql.Connection prepareStatement '{params,throwExp}'  -n 5  -x 3 
watch org.apache.ibatis.mapping.BoundSql getSql '{params,returnObj,throwExp}'  -n 5  -x 3 


# 調(diào)用任意bean中的方法
# 1.先獲取 classLoaderHash
sc -d com.alibaba.dubbo.config.spring.extension.SpringExtensionFactor

# 2.ognl 調(diào)用對(duì)應(yīng) bean 的方法,把 34f5090e 替換為對(duì)于的 classLoaderHash
ognl  -c 34f5090e '#context=@com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory@contexts.iterator.next,#context.getBean("userServiceImpl").find("小明")'

# 當(dāng)傳參是復(fù)雜對(duì)象時(shí)
ognl -c 34f5090e '#context=@com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory@contexts.iterator.next,#data=new Children(), #query=new User(),#query.setChildren(#data),#query.setRequestId("1"), #data.setName("小明"),#context.getBean("userServiceImpl").find(#query)'

# vmtool 命令提供了更簡(jiǎn)單的語(yǔ)法,也可以調(diào)用任意bean中的方法
vmtool --action getInstances  --className org.springframework.context.ApplicationContext --express 'instances[0].getBean("userServiceImpl").find("小明")'


# 動(dòng)態(tài)修改 bean 屬性值
# 本質(zhì)原理就是先獲取 bean 實(shí)例,通過(guò)反射去修改對(duì)應(yīng)屬性值
ognl -c 34f5090e org.ClassLoader
'#context=@com.alibaba.dubbo.config.spring.extension.SpringExtensionFactory@contexts.iterator.next, #instence=#context.getBean("userServiceImpl"),#fieldObj=@com.User@class.getDeclaredField("age"),#fieldObj.setAccessible(true), #fieldObj.set(#instence,18)'

# 除了 ognl 也可以通過(guò) vmtool 去獲取 bean
vmtool --action getInstances  --className org.springframework.context.ApplicationContext --express 'instances[0].getBean("userServiceImpl")'

Arthas 的強(qiáng)大之處確實(shí)令人驚嘆!本文希望能夠啟發(fā)您去探索更多關(guān)于 Arthas 的用法和功能,相信它會(huì)為您的開(kāi)發(fā)工作帶來(lái)很大的幫助和便利。

責(zé)任編輯:趙寧寧 來(lái)源: Java隨想錄
相關(guān)推薦

2023-06-16 08:36:25

多線(xiàn)程編程數(shù)據(jù)競(jìng)爭(zhēng)

2019-09-06 09:00:00

開(kāi)發(fā)技能代碼

2022-08-24 08:16:33

容器安全容器

2023-04-09 16:34:49

JavaSemaphore開(kāi)發(fā)

2022-07-25 14:24:53

Docker容器安全

2022-07-12 08:00:31

命令Kubernetes應(yīng)用程序

2023-09-27 23:57:21

2023-10-26 12:01:30

Golang字符串

2019-01-16 09:00:00

DevOps性能測(cè)試軟件

2024-01-15 08:00:00

開(kāi)發(fā)API文檔集成

2019-05-16 09:00:06

云原生監(jiān)控日志管理

2020-05-25 11:14:59

代碼程序開(kāi)發(fā)

2023-02-07 15:33:16

云遷移數(shù)據(jù)中心云計(jì)算

2024-12-12 09:02:35

2016-10-19 21:56:26

2023-09-12 13:48:47

2020-04-21 11:44:39

威脅建模框架安全工具

2023-04-06 00:15:03

JavaReentrantL線(xiàn)程

2025-07-29 09:06:04

2025-04-11 10:13:00

數(shù)據(jù)庫(kù)APIFastAPI
點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

69视频在线播放| 欧美色男人天堂| 国产亚洲精品自在久久| 亚洲va在线观看| 国产精品免费大片| 91福利在线导航| 尤物国产精品| 天堂成人在线观看| 久久精品国产亚洲a| 欧美黄色片视频| 精品无人区无码乱码毛片国产| 青草综合视频| 日韩美女视频一区二区| 国产一区二区高清视频| 中文字幕 日韩有码| 国产综合欧美| 亚洲精品视频网上网址在线观看| 在线黄色免费观看| 超碰成人av| 国产精品久久久久久久久动漫| 国产91亚洲精品一区二区三区| 中文字幕在线天堂| 亚洲黄色三级| www.日韩免费| 欧美黄色激情视频| 动漫av一区| 678五月天丁香亚洲综合网| 黄色片视频在线免费观看| 26uuu亚洲电影在线观看| 国产亚洲成av人在线观看导航| 97视频中文字幕| 亚洲视频在线免费播放| 另类av一区二区| 九九九久久久久久| 四虎影视一区二区| 少妇精品久久久一区二区三区| 欧美哺乳videos| 伊人国产精品视频| 国产成人免费精品| 精品久久久久久久中文字幕| www.亚洲成人网| 黄色免费在线看| 国产精品久久久久永久免费观看 | 欧美激情影院| 日韩精品在线看片z| а 天堂 在线| 日韩三级一区| 欧美精品一卡两卡| 成人日韩在线视频| 日韩在线电影| 91.com视频| 日韩成人av免费| 懂色av色香蕉一区二区蜜桃| 欧美日韩精品电影| 中文字幕第88页| 欧美韩国日本| 欧美一级黄色片| wwwww在线观看| 91蝌蚪精品视频| 精品处破学生在线二十三| 风韵丰满熟妇啪啪区老熟熟女| 国产午夜精品一区在线观看| 日韩一区二区三区在线| 伊人影院在线观看视频| 视频欧美一区| 亚洲成人在线网| 亚洲av网址在线| 九九久久成人| 国产一区二区久久精品| 亚洲一级理论片| 91精品啪在线观看国产18 | 国产一区电影| 久久老女人爱爱| 日韩一区免费观看| 巨大荫蒂视频欧美大片| 亚洲人成网站色在线观看| 一本大道东京热无码aⅴ| 丁香花在线高清完整版视频| 午夜私人影院久久久久| 麻豆av免费在线| 日韩电影精品| 亚洲国产成人在线播放| 无码h肉动漫在线观看| 日韩欧美高清| 欧美国产日韩视频| 国产欧美一区二区三区在线看蜜臂| 国产欧美一区二区色老头| 国产成人精品在线观看| 国产又粗又猛视频| 成人精品免费看| 日韩av在线电影观看| а√资源新版在线天堂| 午夜欧美视频在线观看| 国产高潮免费视频| 日韩精品一区二区三区中文字幕| 日韩精品视频免费| 夫妇交换中文字幕| 亚洲视频中文| 国产精品视频网站| 99热在线只有精品| 久久久不卡网国产精品一区| 偷拍盗摄高潮叫床对白清晰| av在线理伦电影| 欧美日韩三级一区| 亚洲色图欧美另类| 激情五月综合网| 欧美激情一区二区三区高清视频| 国产精品suv一区二区三区| 麻豆精品久久精品色综合| 国产一区二区三区色淫影院| 午夜免费视频在线国产| 天天色天天操综合| 911av视频| 国内成人自拍| 91av成人在线| a级片在线播放| 欧美国产日韩亚洲一区| 成人午夜精品久久久久久久蜜臀| 久草综合在线| 亚洲欧美一区二区三区久久| 久久免费视频精品| 激情综合一区二区三区| 日本一区视频在线播放| 九色porny视频在线观看| 日韩区在线观看| 99成人在线观看| 日本成人中文字幕| 麻豆传媒一区二区| 国产精品一区hongkong| 日韩午夜三级在线| av在线免费播放网址| 久久婷婷久久| 另类小说综合网| 2021天堂中文幕一二区在线观| 69堂成人精品免费视频| 亚洲色图27p| 久久精品国产免费| 天堂精品一区二区三区| 日韩电影毛片| 日韩成人网免费视频| 久久精品视频久久| 国产99久久久国产精品潘金网站| youjizz.com亚洲| 日韩综合久久| 久久精品国产成人| 91精品国产乱码久久久| 国产精品久久久久久久裸模| 天天碰免费视频| 精品国产一区二区三区av片| 国产999在线观看| 国产在线你懂得| 欧美在线视频你懂得| 婷婷色一区二区三区| 免费一区视频| 日本不卡一区二区三区在线观看| 黄色亚洲网站| 亚洲人成人99网站| 波多野结衣小视频| 欧美韩国日本综合| 国产又黄又猛又粗又爽的视频| 精品久久中文| 国产日韩av高清| 成人午夜在线影视| 欧美成人免费网站| 日韩久久久久久久久| 99re6这里只有精品视频在线观看 99re8在线精品视频免费播放 | 囯产精品久久久久久| 亚洲不卡一区二区三区| 国产精品一级黄片| 久久久久免费| 一区二区国产日产| 秋霞一区二区| 性视频1819p久久| 天天干,夜夜爽| 一本大道久久a久久精品综合| x88av在线| 国产呦萝稀缺另类资源| av日韩在线看| 日韩高清影视在线观看| 国产精品久久婷婷六月丁香| 黄色av电影在线观看| 精品噜噜噜噜久久久久久久久试看 | 五月天婷婷在线观看视频| 欧美精品黄色| 蜜桃成人免费视频| 国产一区高清| 久久免费国产精品1| 户外极限露出调教在线视频| 在线播放欧美女士性生活| 国产一级aa大片毛片| 久久影视一区二区| 色噜噜狠狠一区二区| 欧美午夜不卡| 日本在线观看一区二区三区| 99精品女人在线观看免费视频| 欧美极品欧美精品欧美视频| 免费国产在线观看| 欧美日韩精品二区第二页| 国产精品99精品无码视| 欧美国产一区二区| jjzzjjzz欧美69巨大| 日韩电影在线一区| 免费看欧美黑人毛片| 日韩亚洲一区在线| 国产专区一区二区| 羞羞视频在线观看一区二区| 欧美一区视频在线| a视频在线播放| 亚洲色图偷窥自拍| 免费观看国产精品| 欧美日韩免费一区二区三区| 国产精品美女久久久久av爽| 亚洲精品一卡二卡| 少妇视频在线播放| 91亚洲精品乱码久久久久久蜜桃| 污视频在线观看免费网站| 肉色丝袜一区二区| 3d动漫一区二区三区| 91av精品| 伊人久久大香线蕉精品| 亚洲福利网站| 国产日韩精品推荐| 日韩欧美高清一区二区三区| 国产精品视频内| 怡红院成人在线| 97视频在线观看免费高清完整版在线观看 | 久久精品久久久久久国产 免费| 天天干天天爽天天操| 日韩写真欧美这视频| 亚洲天堂avav| 在线日韩国产精品| 中文字幕视频网站| 亚洲成av人片一区二区| 久久在线视频精品| 亚洲免费观看高清| 日本高清黄色片| 久久精品人人做人人综合| 国产精品无码毛片| a级高清视频欧美日韩| 最新版天堂资源在线| 国产成人在线视频免费播放| 成人免费播放视频| 国产中文字幕精品| 色网站在线视频| 狠狠色丁香婷婷综合久久片| 亚洲综合激情视频| 紧缚捆绑精品一区二区| 999久久久精品视频| 久久66热re国产| 色18美女社区| 国产精品亚洲а∨天堂免在线| 两性午夜免费视频| 国产精品一区二区黑丝| 国产sm在线观看| 国产成a人亚洲精品| 俄罗斯黄色录像| 成人app下载| 国产 中文 字幕 日韩 在线| 久久久www免费人成精品| 日本美女xxx| 中文字幕日韩av资源站| 成年人av电影| 亚洲国产一区视频| 欧美另类一区二区| 日韩欧美综合在线视频| 国产乱码77777777| 欧美无人高清视频在线观看| 国产又黄又粗又猛又爽| 欧美一级黄色录像| 色婷婷av一区二区三| 日韩高清av在线| 国产精品久久一区二区三区不卡| 夜夜嗨av色综合久久久综合网 | 亚洲日本一区二区| 免费网站看av| 色综合婷婷久久| 一女二男一黄一片| 欧美tickling网站挠脚心| 亚洲aaa在线观看| 国产亚洲美女久久| 国产精品一区二区三区视频网站| 欧美黑人又粗大| 色综合一本到久久亚洲91| 成人网中文字幕| 都市激情久久| 视频一区在线免费观看| 天天天综合网| 男人用嘴添女人下身免费视频| 久久婷婷久久| 国产ts在线观看| 国产亚洲综合在线| 农村妇女精品一区二区| 日韩欧美有码在线| 国产免费不卡视频| 国产丝袜一区二区三区| 国产一区久久精品| 欧美一级大片在线观看| 成人免费91| 久久久一本精品99久久精品| 99久久这里只有精品| 精品国产一区三区| 激情综合色播五月| 蜜桃传媒一区二区亚洲av | 亚洲天堂成人在线| 视频在线观看入口黄最新永久免费国产| 欧美尤物巨大精品爽| 激情不卡一区二区三区视频在线| 久久久久久久有限公司| 亚洲乱码在线| 中文字幕一区二区三区四区在线视频| 东方欧美亚洲色图在线| 美女福利视频网| 欧美性xxxx极品hd欧美风情| 精品人妻一区二区三区浪潮在线| 一区二区三区美女xx视频| 蜜桃视频www网站在线观看| 91中文精品字幕在线视频| 精品免费一区二区| 欧美精品99久久| 国产999精品久久久久久| 亚洲欧美日韩第一页| 黑人精品xxx一区一二区| 亚洲女人18毛片水真多| 久久视频中文字幕| 97成人超碰| 日本一区二区三区视频在线观看 | 中文字幕一区二区av| 波多野结衣xxxx| 国产人成一区二区三区影院| 日日夜夜综合网| 亚洲精品成人网| 91资源在线观看| 国产精品裸体一区二区三区| 亚洲精品一二三区区别| 成人性生交免费看| 亚洲国产精品v| 成人黄色三级视频| 亚洲人午夜精品免费| 性欧美18xxxhd| 精品视频一区在线| 99亚洲伊人久久精品影院红桃| 日本一区二区免费视频| 亚洲国产精品嫩草影院| 亚洲精品一区二区三区四区| 欧美猛交ⅹxxx乱大交视频| 国产激情一区| 丰满人妻一区二区三区53号| 国产精品一级二级三级| 欧美日韩精品亚洲精品| 日韩欧美精品在线| 天堂av资源在线观看| 成人在线资源网址| 一区二区亚洲| 国产又粗又长又爽| 欧美日韩国产一区在线| 青草久久伊人| 国产乱人伦真实精品视频| 欧美疯狂party性派对| 国产高清av片| 亚洲亚洲精品在线观看| 四虎在线视频免费观看| 日本sm极度另类视频| 精品日韩免费| 激情文学亚洲色图| 一区二区三区在线观看网站| 开心激情综合网| 欧美最猛性xxxxx免费| jiujiure精品视频播放| 性生生活大片免费看视频| 亚洲综合视频在线观看| 亚洲欧美日韩精品永久在线| 国产69精品久久久久久| 日韩1区2区| 国产精品91av| 欧美香蕉大胸在线视频观看| 国产裸舞福利在线视频合集| 91麻豆国产精品| 精品动漫3d一区二区三区免费| 亚洲中文字幕无码av| 在线免费不卡视频| av中文字幕在线播放| 九色综合婷婷综合| 免费成人在线视频观看| 久久精品一区二区三| 亚洲美女精品成人在线视频| 青草综合视频| 国产黄色一级网站| 中文字幕一区免费在线观看| 色一情一乱一区二区三区| 国产精品99免视看9| 国产中文一区| 亚洲色图日韩精品| 精品福利在线导航| 国外成人福利视频| 亚洲美免无码中文字幕在线| 中文字幕巨乱亚洲| 欧美一区二区黄片| 国产在线观看精品| 国产一级一区二区| 日本精品人妻无码77777|