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

1、运行脚本

程序的目录结构如下

[root@bogon SocketDxpTaxi]# ls
config  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
#设置CLASSPATH
CLASSPATH=$CLASSPATH:$APP_HOME/SocketDxpTaxi.jar
#循环将lib文件夹下所有的jar添加到CLASSPATH
for 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 1
esac
exit 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

  • 5
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

大扑棱蛾子

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值