事情的起因
:这些日子在部署Java程序时发现一个很让人受不了的事情,就是每次要重启Java的APP程序时就必须先PS出来进程ID,然后再用Kill去杀死进程,但如果服务器只部署一两个Java程序的情况下,这种操作还是可以让人接受的,但如果服务器有几个或者几十个Java程序时就让人很郁闷了,又加上启动Java程序时使用-cp来加载jar库文件,一ps就出来一大堆的java及jar。。。。。再怎么grep也还是看了眼花。
查找解决方案
:平时用Linux有时会看到pid文件,说白了就是启动程序后产生的标识进程ID的文件,所以产生了自己也创建自己的pid文件,这样不就可以有效地区分Java的各个程序了吗? 有了想法,当然就去实现,或者这就是当过程序员的一种特性。
尝试一(失败)
:
一开始我想着反正java程序也是靠bash来启动,看有没有执行命令后就返回pid号的命令,找了一下发现有如下方式:
#!/bin/bash
pid=`echo "test pid vange"`
echo $pid
但试过后就发现不太ok,这个命令加上`只是返回执行命令后的字符,如果硬要用这个方式那么你要修改你的java代码,就是执行java程序后,让java打印自身的pid号(这个要通过分析java的XXX标识(忘记了),还要去处理这些字符,最要命是不通用)然后就不再输出任何内容。相信没有多少个开发人员愿意去为了更好地管理硬修改代码。这个方案也就只能否决掉。
尝试二(失败)
:
第一方案不行,再继续找解决方法,再看看Bash的基本变量,发现有个可以试一下:
#!/bin/bash
pid=`echo "test pid vange"`
echo $!
这个 $! 是表示 上一次运行命令的返回 ,如果正确 的话也就返回0 。。。。所以这个方案就否决了。
尝试三(成功)
:
借鉴平时使用的/etc/ini.d/ntpd的代码,终于找到了突破口:start-stop-daemon (没错,就是你了)
start-stop-daemon是一个专门创建系统后台运行进程的命令,存放于/sbin/start-stop-daemon(debian上),看来还不让平常人用,但其权限是一般用户可以使用的,看来也不是有什么权限漏洞。但要给一般用户需要复制到/bin目录下才比较方便
cp /sbin/start-stop-daemon /bin
现在用一般用户vange也可以使用了。接下来就是做个测试例子了:
#!/bin/bash
start-stop-daemon --start --quiet --pidfile /home/vange/xx.pid -m --exec /bin/tailf -- /home/vange/log
命令格式简单(也不算简单),主要注意点有两个:
1、-- 命令里面有这个符号表示 后面的参数不作处理 直接传递给命令(--exec 部分)
2、-m (--make-pidfile)参数这个参数表示自动创建(因为这个参数差点以为不可行的方案)
运行命令,然后可以查看开另外一个终端,ps我们刚运行的命令(它一直都在)
ps -ef|grep tail
vange 3036 2029 0 21:34 pts/0 00:00:00 /bin/tailf /home/vange/log
vange 3050 2390 0 21:44 pts/4 00:00:00 grep tail
看到pid是3036
再查看一下我们创建的PID文件:
cat /home/vange/xx.pid
3036
很好,这就是我们要得到的PID啦!
例子就在这里,现在可以根据 这个去实现Java程序的管理了。再不用敢让别人去随便Kill
关于如何停止这个程序,请参看start-stop-daemon命令参数!
强调一点:停止程序一定要加上 -p (--pidfile) 参数,如果没有加上就很恐怖了!!它就是一个 killall
这个可不是闹着玩的!一下全部的java都关了,你又不清楚要启动哪个来补救,怕都来不及,赶快找运营人员(如果没有运营就只能找老大反映情况(如果老大都不清楚,那就等着出状况被骂吧!))
====================================
找了个一钟头资料,又加上码了半个多小时的字,看来发文章真不是很容易做到的,
希望一篇文章能减小你重复找资料的时间和对Java程序管理上有帮助。
====================================