Java程序在Linux中实现后台运行

来源:互联网 发布:pdg2pdf for mac 编辑:程序博客网 时间:2024/05/21 12:16

1、运行脚本

程序的目录结构如下

[root@bogon SocketDxpTaxi]# lsconfig  lib  logs  run.sh  SocketDxpTaxi.jar[root@bogon SocketDxpTaxi]# find../run.sh./lib./lib/spring-data-commons-1.9.0.RELEASE.jar./lib/aspectjrt-1.8.2.jar......./lib/mina-integration-beans-2.0.9.jar./lib/jandex-1.1.0.Final.jar./SocketDxpTaxi.jar./logs./logs/socket.log./config./config/applicationContext.xml./config/jdbc.properties./config/log4j.properties

其中SocketDxpTaxi.jar为我们要运行的jar,config是程序的配置文件,lib是程序依赖的jar,logs存放日志文件,这几个需要是同级。
eclipse中的程序结构如下
src
– |–com.tiamaes.*
– |–config
通过eclipse将程序导出为jar,一般jar中是包含config的,这时需要把jar中的config文件夹删除,要不然会冲突。

运行jar的脚本如下,这个脚本存在一点问题,Log4j稍微有点问题,但是对运行及日志记录没有影响,日志是通过将所有控制台数据全部写入文件的形式记录的

#!/bin/sh#author:wangchengwei#date:2015-7-7#desc:Run java application#Java的安装目录JAVA_HOME=/usr/lib/java-1.7.0#运行程序所使用的用户OWNER=root#Java程序的目录APP_HOME=/software/TaxiData/SocketDxpTaxi#Main方法的类APP_MAINCLASS=com.tiamaes.gjds.socket.server.MinaServer#日志文件LOG_FILE=$APP_HOME/logs/socket.log#设置CLASSPATHCLASSPATH=$CLASSPATH:$APP_HOME/SocketDxpTaxi.jar#循环将lib文件夹下所有的jar添加到CLASSPATHfor i in "$APP_HOME"/lib/*.jar; do    CLASSPATH="$CLASSPATH":"$i"  done#设置运行参数JAVA_OPTS="-Xms512m -Xmx512m -Xmn256m -Djava.awt.headless=true -XX:MaxPermSize=128m"#echo $CLASSPATH;psid=0#检查Java程序是否运行checkpid(){    javaps=`$JAVA_HOME/bin/jps -l | grep $APP_MAINCLASS`    if [ -n "$javaps" ];then        psid=`echo $javaps | awk '{print $1}'`    else        psid=0    fi}#运行程序start(){    checkpid    if [ $psid -ne 0 ];then        echo "WARN:$APP_MAINCLASS already started!(pid=$psid)"    else        echo "Starting $APP_MAINCLASS..."        JAVA_CMD="nohup $JAVA_HOME/bin/java $JAVA_OPTS -classpath $CLASSPATH $APP_MAINCLASS >> $LOG_FILE 2>&1 &"        su - $OWNER -c "$JAVA_CMD"        checkpid        if [ $psid -ne 0 ];then            echo "Started $APP_MAINCLASS (pid=$psid)[OK]"        else            echo "Started $APP_MAINCLASS [FAILED]"        fi    fi}#停止程序stop(){    checkpid    if [ $psid -ne 0 ];then        echo "Stoping $APP_MAINCLASS...(pid=$psid)"        su - $OWNER -c "kill $psid"        checkpid        if [ $psid -ne 0 ];then            echo "Stoping use kill -9"            su - $OWNER -c "kill -9 $psid"        fi        checkpid        if [ $psid -eq 0 ];then            echo "Stoped $APP_MAINCLASS [OK]"        else            echo "Stoped $APP_MAINCLASS [Failed]"            stop        fi    else        echo "WARN:$APP_MAINCLASS is not runing"    fi}#查看状态status(){    checkpid    if [ $psid -ne 0 ];then        echo "$APP_MAINCLASS is runing (pid=$psid)"    else        echo "$APP_MAINCLASS is not runing"    fi}#帮助信息info() {    echo "System Information:"    echo "****************************"    echo `head -n 1 /etc/issue`    echo `uname -a`    echo    echo "JAVA_HOME=$JAVA_HOME"    echo `$JAVA_HOME/bin/java -version`    echo    echo "APP_HOME=$APP_HOME"    echo "APP_MAINCLASS=$APP_MAINCLASS"    echo "****************************"}#$1表示接收第一个参数,如 ./run.sh start 。则$1就是start case "$1" in    'start')        start        ;;    'stop')        stop        ;;    'restart')        stop        start        ;;    'info')        info        ;;    'status')        status        ;;    *)    echo "Usage: $0 {start|stop|restart|status|info}"    exit 1esacexit 0;

2、知识点解析

shell的基础知识不在赘述,自己百度学习。重点说下几个点。

2.1、运行jar

JAVA_OPTS="-Xms512m -Xmx512m -Xmn256m -Djava.awt.headless=true -XX:MaxPermSize=128m"# java $JAVA_OPTS -classpath $CLASSPATH $APP_MAINCLASS

Java在运行jar是可以设置Java的运行参数、classpath等选项。

Java运行参数主要是内存的设置
-Xms:初始Heap大小,使用的最小内存,cpu性能高时此值应设的大一些
-Xmx:java heap最大值,使用的最大内存
-XX:PermSize:设定内存的永久保存区域
-XX:MaxPermSize:设定最大内存的永久保存区域
-Xmn:young generation的heap大小,一般设置为Xmx的3、4分之一

classpath用于设置jar运行是所依赖jar

2.2、Java中的jps命令

jps(Java Virtual Machine Process Status Tool)是JDK 1.5提供的一个显示当前所有java进程pid的命令,简单实用,非常适合在linux/unix平台上简单察看当前java进程的一些简单情况。
比较常用的参数:
-q 只显示pid,不显示class名称,jar文件名和传递给main 方法的参数
-m 输出传递给main 方法的参数,在嵌入式jvm上可能是null
-m 输出传递给main 方法的参数,在嵌入式jvm上可能是null
-l 输出应用程序main class的完整package名 或者 应用程序的jar文件完整路径名
-v 输出传递给JVM的参数
在本例中我们使用的是jps -l,使用 jps -l | grep $APP_MAINCLASS 可以根据Main方法所在的类名查看进程中是否有我们的程序。然后通过awk得到进程的pid。

2.3、su命令的使用

su - $OWNER -c "$JAVA_CMD"

上面的命令表示使用 $OWNER用户执行命令,-c后面跟命令。这样做的好处就是执行的时候是带有用户的环境变量的,而且能保证我们的应用在我们指定的用户下运行。

2.4、nohup

用途:不挂断地运行命令,说的见简单点就是让程序能够在后台运行。
语法:nohup Command [ Arg … ] [ & ]

描述:nohup 命令运行由 Command 参数和任何相关的 Arg 参数指定的命令,忽略所有挂断(SIGHUP)信号。在注销后使用 nohup 命令运行后台中的程序。要运行后台中的 nohup 命令,添加 & ( 表示”and”的符号)到命令的尾部。

无论是否将 nohup 命令的输出重定向到终端,输出都将附加到当前目录的 nohup.out 文件中。如果当前目录的 nohup.out 文件不可写,输出重定向到 $HOME/nohup.out 文件中。如果没有文件能创建或打开以用于追加,那么 Command 参数指定的命令不可调用。如果标准错误是一个终端,那么把指定的命令写给标准错误的所有输出作为标准输出重定向到相同的文件描述符

意思就是让我们的Java程序在后台运行,并且将程序产生的日志记录到$LOG_FILE中,>表示写入(先清除内容再写入内容),>>表示追加

2>&1的含义

对于& 1 更准确的说应该是文件描述符 1,而1 一般代表的就是STDOUT_FILENO,实际上这个操作就是一个dup2(2)调用.他标准输出到all_result ,然后复制标准输出到文件描述符2(STDERR_FILENO),其后果就是文件描述符1和2指向同一个文件表项,也可以说错误的输出被合并了.其中0 表示键盘输入 1表示屏幕输出 2表示错误输出.把标准出错重定向到标准输出,然后扔到/DEV/NULL下面去。通俗的说,就是把所有标准输出和标准出错都扔到垃圾桶里面。

2>&1 是将标准出错重定向到标准输出,这里的标准输出已经重定向到了$LOG_FILE文件,即将标准出错也输出到$LOG_FILE文件中

有关详细介绍可以查看这篇博文:http://blog.csdn.net/annicybc/article/details/4814872

0 0