Arthas
هي أداة تشخيص Java مفتوحة المصدر من Alibaba.
يسمح Arthas للمطورين باستكشاف مشكلات الإنتاج لتطبيقات Java وإصلاحها دون تعديل التعليمات البرمجية أو إعادة تشغيل الخوادم.
中文说明/ التوثيق الصيني
في كثير من الأحيان، لا يمكن الوصول إلى شبكة نظام الإنتاج من بيئة التطوير المحلية. إذا تمت مواجهة مشكلات في أنظمة الإنتاج، فمن المستحيل استخدام IDEs لتصحيح أخطاء التطبيق عن بُعد. والأهم من ذلك، أن تصحيح الأخطاء في بيئة الإنتاج أمر غير مقبول، لأنه سيؤدي إلى تعليق جميع الخيوط، مما يؤدي إلى تعليق خدمات الأعمال.
يمكن للمطورين دائمًا محاولة إعادة إنتاج نفس المشكلة في بيئة الاختبار/التدريج. ومع ذلك، يعد هذا أمرًا صعبًا حيث لا يمكن إعادة إنتاج بعض المشكلات بسهولة في بيئة مختلفة، أو حتى تختفي بمجرد إعادة التشغيل.
وإذا كنت تفكر في إضافة بعض السجلات إلى التعليمات البرمجية الخاصة بك للمساعدة في استكشاف المشكلة وإصلاحها، فسيتعين عليك المرور بدورة الحياة التالية؛ الاختبار والتدريج ثم الإنتاج. الوقت هو المال! هذا النهج غير فعال! بالإضافة إلى ذلك، قد لا تكون المشكلة قابلة للتكرار بمجرد إعادة تشغيل JVM، كما هو موضح أعلاه.
تم بناء Arthas لحل هذه المشكلات. يمكن للمطور استكشاف مشكلات الإنتاج الخاصة بك وإصلاحها بسرعة. لا توجد إعادة تشغيل لـ JVM، ولا توجد تغييرات إضافية في التعليمات البرمجية. يعمل Arthas كمراقب، وهو ما لن يؤدي أبدًا إلى تعليق سلاسل الرسائل الموجودة لديك.
arthas-boot
(مستحسن) قم بتنزيل arthas-boot.jar
، ابدأ باستخدام أمر java
:
curl -O https://arthas.aliyun.com/arthas-boot.jar
java -jar arthas-boot.jar
استخدام الطباعة:
java -jar arthas-boot.jar -h
as.sh
يمكنك تثبيت Arthas باستخدام أمر سطر واحد على Linux وUnix وMac. انسخ الأمر التالي والصقه في سطر الأوامر، ثم اضغط على Enter للتشغيل:
curl -L https://arthas.aliyun.com/install.sh | sh
سيقوم الأمر أعلاه بتنزيل البرنامج النصي bootstrap as.sh
إلى الدليل الحالي. يمكنك نقله إلى أي مكان آخر تريده، أو وضع موقعه في $PATH
.
يمكنك الدخول إلى الواجهة التفاعلية عن طريق تنفيذ as.sh
أو تنفيذ as.sh -h
لمزيد من معلومات المساعدة.
تعرف على ما يأكل وحدة المعالجة المركزية لديك (مرتبة حسب أعلى استخدام لوحدة المعالجة المركزية) وما يحدث هناك في لمحة واحدة:
$ thread -n 3
" as-command-execute-daemon " Id=29 cpuUsage=75% RUNNABLE
at sun.management.ThreadImpl.dumpThreads0(Native Method)
at sun.management.ThreadImpl.getThreadInfo(ThreadImpl.java:440)
at com.taobao.arthas.core.command.monitor200.ThreadCommand $1 .action(ThreadCommand.java:58)
at com.taobao.arthas.core.command.handler.AbstractCommandHandler.execute(AbstractCommandHandler.java:238)
at com.taobao.arthas.core.command.handler.DefaultCommandHandler.handleCommand(DefaultCommandHandler.java:67)
at com.taobao.arthas.core.server.ArthasServer $4 .run(ArthasServer.java:276)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor $Worker .run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:745)
Number of locked synchronizers = 1
- java.util.concurrent.ThreadPoolExecutor $Worker @6cd0b6f8
" as-session-expire-daemon " Id=25 cpuUsage=24% TIMED_WAITING
at java.lang.Thread.sleep(Native Method)
at com.taobao.arthas.core.server.DefaultSessionManager $2 .run(DefaultSessionManager.java:85)
" Reference Handler " Id=2 cpuUsage=0% WAITING on java.lang.ref.Reference $Lock @69ba0f27
at java.lang.Object.wait(Native Method)
- waiting on java.lang.ref.Reference $Lock @69ba0f27
at java.lang.Object.wait(Object.java:503)
at java.lang.ref.Reference $ReferenceHandler .run(Reference.java:133)
قم بفك صفك باستخدام طلقة واحدة:
$ jad javax . servlet . Servlet
ClassLoader :
+- java . net . URLClassLoader @ 6108 b2d7
+- sun . misc . Launcher$AppClassLoader @ 18 b4aac2
+- sun . misc . Launcher$ExtClassLoader @ 1d df84b8
Location :
/ Users / xxx / work / test / lib / servlet - api . jar
/*
* Decompiled with CFR 0_122.
*/
package javax . servlet ;
import java . io . IOException ;
import javax . servlet . ServletConfig ;
import javax . servlet . ServletException ;
import javax . servlet . ServletRequest ;
import javax . servlet . ServletResponse ;
public interface Servlet {
public void init ( ServletConfig var1 ) throws ServletException ;
public ServletConfig getServletConfig ();
public void service ( ServletRequest var1 , ServletResponse var2 ) throws ServletException , IOException ;
public String getServletInfo ();
public void destroy ();
}
مترجم الذاكرة، يجمع ملفات .java
إلى ملفات .class
في الذاكرة.
$ mc /tmp/Test.java
قم بتحميل ملفات *.class
الخارجية لإعادة تحويل/تبديل سريع للفئات المحملة في JVM.
retransform /tmp/Test.class
retransform -c 327a647b /tmp/Test.class /tmp/Test $ Inner.class
ابحث في أي فئة محملة بمعلومات مفصلة.
$ sc -d org.springframework.web.context.support.XmlWebApplicationContext
class-info org.springframework.web.context.support.XmlWebApplicationContext
code-source /Users/xxx/work/test/WEB-INF/lib/spring-web-3.2.11.RELEASE.jar
name org.springframework.web.context.support.XmlWebApplicationContext
isInterface false
isAnnotation false
isEnum false
isAnonymousClass false
isArray false
isLocalClass false
isMemberClass false
isPrimitive false
isSynthetic false
simple-name XmlWebApplicationContext
modifier public
annotation
interfaces
super-class +-org.springframework.web.context.support.AbstractRefreshableWebApplicationContext
+-org.springframework.context.support.AbstractRefreshableConfigApplicationContext
+-org.springframework.context.support.AbstractRefreshableApplicationContext
+-org.springframework.context.support.AbstractApplicationContext
+-org.springframework.core.io.DefaultResourceLoader
+-java.lang.Object
class-loader +-org.apache.catalina.loader.ParallelWebappClassLoader
+-java.net.URLClassLoader@6108b2d7
+-sun.misc.Launcher $AppClassLoader @18b4aac2
+-sun.misc.Launcher $ExtClassLoader @1ddf84b8
classLoaderHash 25131501
الحصول على كائنات في الكومة تمثل مثيلات للفئة المحددة.
$ vmtool --action getInstances --className java.lang.String --limit 10
@String[][
@String[com/taobao/arthas/core/shell/session/Session],
@String[com.taobao.arthas.core.shell.session.Session],
@String[com/taobao/arthas/core/shell/session/Session],
@String[com/taobao/arthas/core/shell/session/Session],
@String[com/taobao/arthas/core/shell/session/Session.class],
@String[com/taobao/arthas/core/shell/session/Session.class],
@String[com/taobao/arthas/core/shell/session/Session.class],
@String[com/],
@String[java/util/concurrent/ConcurrentHashMap $ValueIterator ],
@String[java/util/concurrent/locks/LockSupport],
]
عرض مكدس الاستدعاءات الخاص بـ test.arthas.TestStack#doGet
:
$ stack test.arthas.TestStack doGet
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 286 ms.
ts=2018-09-18 10:11:45 ; thread_name=http-bio-8080-exec-10 ; id=d9 ; is_daemon=true ; priority=5 ; TCCL=org.apache.catalina.loader.ParallelWebappClassLoader@25131501
@test.arthas.TestStack.doGet ()
at javax.servlet.http.HttpServlet.service(HttpServlet.java:624)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:731)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:303)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:241)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:208)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:220)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:110)
...
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:169)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:116)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:451)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1121)
at org.apache.coyote.AbstractProtocol $AbstractConnectionHandler .process(AbstractProtocol.java:637)
at org.apache.tomcat.util.net.JIoEndpoint $SocketProcessor .run(JIoEndpoint.java:316)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at java.util.concurrent.ThreadPoolExecutor $Worker .run(ThreadPoolExecutor.java:617)
at org.apache.tomcat.util.threads.TaskThread $WrappingRunnable .run(TaskThread.java:61)
at java.lang.Thread.run(Thread.java:745)
تعرف على ما يبطئ استدعاء الطريقة باستخدام أمر التتبع:
شاهد المعلمة الأولى والاستثناء الذي تم طرحه لـ test.arthas.TestWatch#doGet
فقط إذا تم طرح الاستثناء.
$ watch test.arthas.TestWatch doGet {params[0], throwExp} -e
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 65 ms.
ts=2018-09-18 10:26:28 ; result=@ArrayList[
@RequestFacade[org.apache.catalina.connector.RequestFacade@79f922b2],
@NullPointerException[java.lang.NullPointerException],
]
مراقبة إحصائيات استدعاء طريقة معينة، بما في ذلك إجمالي عدد الاستدعاءات ومتوسط وقت الاستجابة ومعدل النجاح وكل 5 ثوانٍ:
$ monitor -c 5 org.apache.dubbo.demo.provider.DemoServiceImpl sayHello
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 109 ms.
timestamp class method total success fail avg-rt(ms) fail-rate
----------------------------------------------------------------------------------------------------------------------------
2018-09-20 09:45:32 org.apache.dubbo.demo.provider.DemoServiceImpl sayHello 5 5 0 0.67 0.00%
timestamp class method total success fail avg-rt(ms) fail-rate
----------------------------------------------------------------------------------------------------------------------------
2018-09-20 09:45:37 org.apache.dubbo.demo.provider.DemoServiceImpl sayHello 5 5 0 1.00 0.00%
timestamp class method total success fail avg-rt(ms) fail-rate
----------------------------------------------------------------------------------------------------------------------------
2018-09-20 09:45:42 org.apache.dubbo.demo.provider.DemoServiceImpl sayHello 5 5 0 0.43 0.00%
قم بتسجيل بيانات استدعاء الطريقة، حتى تتمكن من التحقق من معلمات استدعاء الطريقة والقيمة التي تم إرجاعها والاستثناءات التي تم طرحها لاحقًا. إنه يعمل كما لو كان بإمكانك العودة وإعادة تشغيل استدعاء الطريقة السابقة عبر نفق الوقت.
$ tt -t org.apache.dubbo.demo.provider.DemoServiceImpl sayHello
Press Ctrl+C to abort.
Affect(class-cnt:1 , method-cnt:1) cost in 75 ms.
INDEX TIMESTAMP COST(ms) IS-RET IS-EXP OBJECT CLASS METHOD
-------------------------------------------------------------------------------------------------------------------------------------
1000 2018-09-20 09:54:10 1.971195 true false 0x55965cca DemoServiceImpl sayHello
1001 2018-09-20 09:54:11 0.215685 true false 0x55965cca DemoServiceImpl sayHello
1002 2018-09-20 09:54:12 0.236303 true false 0x55965cca DemoServiceImpl sayHello
1003 2018-09-20 09:54:13 0.159598 true false 0x55965cca DemoServiceImpl sayHello
1004 2018-09-20 09:54:14 0.201982 true false 0x55965cca DemoServiceImpl sayHello
1005 2018-09-20 09:54:15 0.214205 true false 0x55965cca DemoServiceImpl sayHello
1006 2018-09-20 09:54:16 0.241863 true false 0x55965cca DemoServiceImpl sayHello
1007 2018-09-20 09:54:17 0.305747 true false 0x55965cca DemoServiceImpl sayHello
1008 2018-09-20 09:54:18 0.18468 true false 0x55965cca DemoServiceImpl sayHello
$ classloader
name numberOfInstances loadedCountTotal
BootstrapClassLoader 1 3346
com.taobao.arthas.agent.ArthasClassloader 1 1262
java.net.URLClassLoader 2 1033
org.apache.catalina.loader.ParallelWebappClassLoader 1 628
sun.reflect.DelegatingClassLoader 166 166
sun.misc.Launcher $AppClassLoader 1 31
com.alibaba.fastjson.util.ASMClassLoader 6 15
sun.misc.Launcher $ExtClassLoader 1 7
org.jvnet.hk2.internal.DelegatingClassLoader 2 2
sun.reflect.misc.MethodUtil 1 1
$ profiler start
Started [cpu] profiling
$ profiler stop
profiler output file: /tmp/demo/arthas-output/20211207-111550.html
OK
عرض نتائج ملف التعريف ضمن إخراج arthas عبر المتصفح:
لدى Arthas أكثر من 120 مستخدمًا مسجلاً، عرض الكل.
مرحبا بكم في تسجيل اسم الشركة في هذا العدد: #111 (حسب ترتيب التسجيل)
هذا المشروع موجود، وذلك بفضل جميع الأشخاص الذين ساهموا.