bingoohuang/blog

JAVA脱离接触之DisableAttachMechanism

Opened this issue · 0 comments

JAVA脱离接触之DisableAttachMechanism

为了安全,关闭一切无关选项(突然想起了特朗普,以美国国家安全为由 ...)。

Alibaba Java诊断利器Arthas的原理

阅读这个

Arthas是阿里巴巴最近开源的一款在线诊断java应用程序的工具,是greys工具的升级版本,深受开发者喜爱。当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决:

  1. 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
  2. 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
  3. 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
  4. 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
  5. 是否有一个全局视角来查看系统的运行状况?
  6. 有什么办法可以监控到JVM的实时运行状态?
  7. Arthas采用命令行交互模式,同时提供丰富的 Tab 自动补全功能,进一步方便进行问题的定位和诊断。

原理解析

  1. attach:jdk1.6新增功能,通过attach机制,可以在jvm运行中,通过pid关联应用
  2. instrument:jdk1.5新增功能,通过instrument俗称javaagent技术,可以修改jvm加载的字节码

然后arthas和其他诊断工具一样,都是先通过attach链接上目标应用,通过instrument动态修改应用程序的字节码达到不重启应用而监控应用的目的。

那么那Attach机制是什么?

继续阅读这里,或者翻墙版本

Attach机制说简单点就是jvm提供一种jvm进程间通信的能力,能让一个进程传命令给另外一个进程,并让它执行内部的一些操作,比如说我们为了让另外一个jvm进程把线程dump出来,那么我们跑了一个jstack的进程,然后传了个pid的参数,告诉它要哪个进程进行线程dump,既然是两个进程,那肯定涉及到进程间通信,以及传输协议的定义,比如要执行什么操作,传了什么参数等。

Attach能做些什么?总结起来说,比如内存dump,线程dump,类信息统计(比如加载的类及大小以及实例个数等),动态加载agent(使用过btrace的应该不陌生),动态设置vm flag(但是并不是所有的flag都可以设置的,因为有些flag是在jvm启动过程中使用的,是一次性的),打印vm flag,获取系统属性等,这些对应的源码attachListener.cpp如下

// names must be of length <= AttachOperation::name_length_max
static AttachOperationFunctionInfo funcs[] = {
  { "agentProperties",  get_agent_properties },
  { "datadump",         data_dump },
  { "dumpheap",         dump_heap },
  { "load",             JvmtiExport::load_agent_library },
  { "properties",       get_system_properties },
  { "threaddump",       thread_dump },
  { "inspectheap",      heap_inspection },
  { "setflag",          set_flag },
  { "printflag",        print_flag },
  { "jcmd",             jcmd },
  { NULL,               NULL }
};

如何关闭Attach功能呢?

根据文档

-XX:+DisableAttachMechanism
Enables the option that disables the mechanism that lets tools attach to the JVM. By default, this option is disabled, meaning that the attach mechanism is enabled and you can use tools such as jcmd, jstack, jmap, and jinfo.

根据一篇博客

Attach API can be disabled on your JVM by setting -XX:+DisableAttachMechanism Java property. When we set the options while starting the Tomcat ,
JAVA_OPTS="-XX:+DisableAttachMechanism"

验证DisableAttachMechanism

  1. 下载验证包:curl -L -O https://alibaba.github.io/arthas/arthas-demo.jar

  2. 启动Demo: java -jar arthas-demo.jar

  3. 启动arthas: java -jar arthas-boot.jar (现行下载curl -L -O https://alibaba.github.io/arthas/arthas-boot.jar),可以看到arthas可以attach成功。

     $ java -jar arthas-boot.jar
     [INFO] arthas-boot version: 3.1.1
     [INFO] Found existing java process, please choose one and hit RETURN.
     * [1]: 23769 arthas-demo.jar
     1
     [INFO] arthas home: /Users/bingoobjca/.arthas/lib/3.1.1/arthas
     [INFO] Try to attach process 23769
     [INFO] Attach process 23769 success.
     [INFO] arthas-client connect 127.0.0.1 3658
       ,---.  ,------. ,--------.,--.  ,--.  ,---.   ,---.
      /  O  \ |  .--. ''--.  .--'|  '--'  | /  O  \ '   .-'
     |  .-.  ||  '--'.'   |  |   |  .--.  ||  .-.  |`.  `-.
     |  | |  ||  |\  \    |  |   |  |  |  ||  | |  |.-'    |
     `--' `--'`--' '--'   `--'   `--'  `--'`--' `--'`-----'
     
     
     wiki      https://alibaba.github.io/arthas
     tutorials https://alibaba.github.io/arthas/arthas-tutorials
     version   3.1.1
     pid       23769
     time      2019-05-29 15:01:24

    同时,Demo程序端,有如下打印:

    Wed May 29 15:01:24 CST 2019 com.taobao.arthas.agent.ArthasClassloader@43d1f1b7     JM.Log:INFO Log root path: /Users/bingoobjca/logs/
    Wed May 29 15:01:24 CST 2019 com.taobao.arthas.agent.ArthasClassloader@43d1f1b7     JM.Log:INFO Set arthas log path: /Users/bingoobjca/logs/arthas
  4. 重新启动Demo java -XX:+DisableAttachMechanism -jar arthas-demo.jar

  5. 重新启动arthas,可以看到,attach失败

    $ java -jar arthas-boot.jar
    [INFO] arthas-boot version: 3.1.1
    [INFO] Found existing java process, please choose one and hit RETURN.
    * [1]: 24086 arthas-demo.jar
    1
    [INFO] arthas home: /Users/bingoobjca/.arthas/lib/3.1.1/arthas
    [INFO] Try to attach process 24086
    [ERROR] Start arthas failed, exception stack trace:
    com.sun.tools.attach.AttachNotSupportedException: The VM does not support the attach         mechanism
    	at     sun.tools.attach.HotSpotAttachProvider.testAttachable(HotSpotAttachProvider.java:162)
    	at sun.tools.attach.BsdAttachProvider.attachVirtualMachine(BsdAttachProvider.java:61)
    	at com.sun.tools.attach.VirtualMachine.attach(VirtualMachine.java:208)
    	at com.taobao.arthas.core.Arthas.attachAgent(Arthas.java:73)
    	at com.taobao.arthas.core.Arthas.<init>(Arthas.java:28)
    	at com.taobao.arthas.core.Arthas.main(Arthas.java:113)
    [ERROR] attach fail, targetPid: 24086
  6. export JAVA_OPTS="-XX:+DisableAttachMechanism"

  7. java $JAVA_OPTS -jar arthas-demo.jar

更多

  1. The most complete list of -XX options for Java JVM
  2. Tomcat configuration recommendations