9.3 实战:自己动手实现远程执行功能

9.3 实战:自己动手实现远程执行功能

不知道读者在做程序维护的时候是否遇到过这类情形:排查问题的过程中,想查看内存中的一些参数值,却苦于没有方法把这些值输出到界面或日志中。又或者定位到某个缓存数据有问题,由于缺少缓存的统一管理界面,不得不重启服务才能清理掉这个缓存。类似的需求有一个共同的特点,那就是只要在服务中执行一小段程序代码,就可以定位或排除问题,但就是偏偏找不到可以让服务器执行临时代码的途径,让人恨不得在服务器上装个后门。这是项目运维中的常见问题,通常解决类问题有以下几种途径:

  • 1)可以使用BTrace^1这类JVMTI工具去动态修改程序中某一部分的运行代码,这部分在第4章有 简要的介绍,类似的JVMTI工具还有阿里巴巴的Arthas^2等。
  • 2)使用JDK 6之后提供了Compiler API,可以动态地编译Java程序,这样虽然达不到动态语言的 灵活度,但让服务器执行临时代码的需求是可以得到解决的。
  • 3)也可以通过“曲线救国”的方式来做到,譬如写一个JSP文件上传到服务器,然后在浏览器中运 行它,或者在服务端程序中加入一个BeanShell Script、JavaScript等的执行引擎(如Mozilla Rhino[^3]) 去执行动态脚本。
  • 4)在应用程序中内置动态执行的功能。

在本章的实战部分,我们将使用前面学到的关于类加载及虚拟机执行子系统的知识去完成在服务端执行临时代码的功能。

[^3]: 网站:http://www.mozilla.org/rhino/,Rhino已被收编入JDK 6中。