设为首页 收藏本站
查看: 816|回复: 0

[经验分享] jetty实施后jps不可用问题

[复制链接]

尚未签到

发表于 2017-2-26 13:43:40 | 显示全部楼层 |阅读模式
背景
     自从公司应用大部分迁移到了jetty后,一些杂七杂吧的问题,陆续的冒上来。 前段时间有很多人问我使用了jetty之后,对应的jps功能无法正常使用,jinfo/jstack等等这些命令都正常。

原因分析
  java进程启动后,会在$TMP(%TMP%)/hsperfdata_$username 创建一个perfData数据,用于jvmstat一些统计数据(可以看一下神人的神帖:http://rednaxelafx.iteye.com/blog/796343)。
  可以做个尝试, 启动一个main函数: 

public class InstrumentServer {
private String ip;
private String port;
public InstrumentServer(String ip, String port){
this.ip = ip;
this.port = port;
}
public int start(String ip, String port) {
System.out.println("start at : " + ip + ":" + port);
return 123;
}
public void stop() {
this.ip = null;
this.port = null;
}
public String getIp() {
return ip;
}
public void setIp(String ip) {
this.ip = ip;
}
public String getPort() {
return port;
}
public void setPort(String port) {
this.port = port;
}
public static void main(String args[]) throws Exception {
for (int i = 0; i < 1000; i++) {
InstrumentServer server = new InstrumentServer(String.valueOf(i), String.valueOf(i));
server.start(String.valueOf(i), String.valueOf(i));
Thread.sleep(1000);
server.stop();
}
}
}
  jvm参数:  

-XX:-UsePerfData
  几个现象:
  1. 这时/tmp/hsperfdata_$username 下发现没有对应的java进程的文件
  2. jps发现没有对应该main函数的进程信息
  3. jinfo,jstack,jmap均可以使用,jstat功能不能使用(gc信息获取)
  关于该jvm参数的,可以查看http://stackoverflow.com/questions/76327/how-can-i-prevent-java-from-creating-hsperfdata-files
  最后回过头,看一下最初的问题,为啥jps失效



  • 目前公司同事测试来看,jdk16_23/24开始,jvm启动时产生进程号的临时文件目录不是使用$TMP(%TMP%)/hsperfdata,而是使用-Djava.io.tmpdir指定的目录。
  • 凑巧使用了jetty后,为了解决每次jetty都可以清除war包解压后的临时文件,所以强制指定了-Djava.io.tmpdir=${jetty_server}/tmp/ , 模拟了jboss_server的方式,所有的jetty运行的信息都会保存到一个${jetty_server}目录下,每次重启都会清空该目录。避免上一次的结果对下一次启动的影响,以前遇到过部署内容一直被缓存的问题,所以采取了这样的一种暴力删除的方式。
    war解压临时目录算法如下:
    /**
    * Get a temporary directory in which to unpack the war etc etc.
    * The algorithm for determining this is to check these alternatives
    * in the order shown:
    *
    * <p>A. Try to use an explicit directory specifically for this webapp:</p>
    * <ol>
    * <li>
    * Iff an explicit directory is set for this webapp, use it. Do NOT set
    * delete on exit.
    * </li>
    * <li>
    * Iff javax.servlet.context.tempdir context attribute is set for
    * this webapp && exists && writeable, then use it. Do NOT set delete on exit.
    * </li>
    * </ol>
    *
    * <p>B. Create a directory based on global settings. The new directory
    * will be called "Jetty_"+host+"_"+port+"__"+context+"_"+virtualhost
    * Work out where to create this directory:
    * <ol>
    * <li>
    * Iff $(jetty.home)/work exists create the directory there. Do NOT
    * set delete on exit. Do NOT delete contents if dir already exists.
    * </li>
    * <li>
    * Iff WEB-INF/work exists create the directory there. Do NOT set
    * delete on exit. Do NOT delete contents if dir already exists.
    * </li>
    * <li>
    * Else create dir in $(java.io.tmpdir). Set delete on exit. Delete
    * contents if dir already exists.
    * </li>
    * </ol>
    **/

  • 最后jps根本不可能知道要去哪里找这个目录,除非在一个固定的目录中查找这 个文件的指示,那还如直接在那个固定的目录直接写pid,之前的$TMP(%TMP%)/hsperfdata_${username},相对jvm来说,它就是一个固定的目录。而现在却可以根据参数改变,但JPS无法知道这个参数,所以无法获取PID。

  对应的jdk bug描述: http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7021676 

解决


  • 就是先用jdk 1.6.0-18,等jdk bug修复。
  • 根据jetty的war的解压算法,避免使用-Djava.io.tmpdir, ((jetty.home)/work和WEB-INF/work目前来看都不满足需求)
  • hack jetty的war解压算法,添加自定义的参数变量进行控制,(需要考虑后期的jetty升级成本,不是很可取)

最后,只能暂时使用jdk 1.6.0-18,等jdk bug的修复。

其他
  众所周知,linux下/tmp/目录下的文件会被进行定时删除,那是不是/tmp/hsperfdata_${username},也存在同样的风险? 过一段时间后,对应的jps和jstat功能都会出现不可用。
  redhat下有tmpwatch任务进行控制,在/etc/cron.daily/tmpwatch有对应的脚本,可以设置排查下对应的/tmp/hsperfdata_*的目录的清理工作,让jvm自己来保证,保证jps,jstat命令的可用
  具体可以看一下, http://sdh5724.iteye.com/blog/600803

运维网声明 1、欢迎大家加入本站运维交流群:群②:261659950 群⑤:202807635 群⑦870801961 群⑧679858003
2、本站所有主题由该帖子作者发表,该帖子作者与运维网享有帖子相关版权
3、所有作品的著作权均归原作者享有,请您和我们一样尊重他人的著作权等合法权益。如果您对作品感到满意,请购买正版
4、禁止制作、复制、发布和传播具有反动、淫秽、色情、暴力、凶杀等内容的信息,一经发现立即删除。若您因此触犯法律,一切后果自负,我们对此不承担任何责任
5、所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其内容的准确性、可靠性、正当性、安全性、合法性等负责,亦不承担任何法律责任
6、所有作品仅供您个人学习、研究或欣赏,不得用于商业或者其他用途,否则,一切后果均由您自己承担,我们对此不承担任何法律责任
7、如涉及侵犯版权等问题,请您及时通知我们,我们将立即采取措施予以解决
8、联系人Email:admin@iyunv.com 网址:www.yunweiku.com

所有资源均系网友上传或者通过网络收集,我们仅提供一个展示、介绍、观摩学习的平台,我们不对其承担任何法律责任,如涉及侵犯版权等问题,请您及时通知我们,我们将立即处理,联系人Email:kefu@iyunv.com,QQ:1061981298 本贴地址:https://www.yunweiku.com/thread-347520-1-1.html 上篇帖子: 彩票计算JAVA版(四)内置WEB容器jetty 下篇帖子: 直接在ECLIPSE中JETTY调试方式
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

扫码加入运维网微信交流群X

扫码加入运维网微信交流群

扫描二维码加入运维网微信交流群,最新一手资源尽在官方微信交流群!快快加入我们吧...

扫描微信二维码查看详情

客服E-mail:kefu@iyunv.com 客服QQ:1061981298


QQ群⑦:运维网交流群⑦ QQ群⑧:运维网交流群⑧ k8s群:运维网kubernetes交流群


提醒:禁止发布任何违反国家法律、法规的言论与图片等内容;本站内容均来自个人观点与网络等信息,非本站认同之观点.


本站大部分资源是网友从网上搜集分享而来,其版权均归原作者及其网站所有,我们尊重他人的合法权益,如有内容侵犯您的合法权益,请及时与我们联系进行核实删除!



合作伙伴: 青云cloud

快速回复 返回顶部 返回列表