タイミングcronjob呼び出しJavaプログラム

8144 ワード

linux環境に導入されたJavaエンタープライズアプリケーションのバックグラウンドでは、夜中に多くのタイミングでタスクが実行されることがよくあります.この記事では、shellスクリプトを使用してJavaプログラムを呼び出す方法をまとめ、忘れないようにします.
1. setupenv.sh
export APP_HOME=`pwd`

if [ -z "$JAVA_HOME" ] ; then
  JAVA=`which java`
  if [ -z "$JAVA" ] ; then
    echo "Cannot find JAVA. Please set your PATH."
    exit 1
  fi
  JAVA_BIN=`dirname $JAVA`
  JAVA_HOME=$JAVA_BIN/..
fi

PATH_SEPARATOR=':'
if [ $OSTYPE = "cygwin32" ] ; then
   PATH_SEPARATOR=';'
fi
if [ $OSTYPE = "cygwin" ] ; then
   PATH_SEPARATOR=';'
fi
JAVA=$JAVA_HOME/bin/java

CLASSPATH=$JAVA_HOME/lib/tools.jar
CLASSPATH=`echo ${APP_HOME}/lib/*.jar | tr ' ' ${PATH_SEPARATOR}`${PATH_SEPARATOR}${CLASSPATH}
CLASSPATH=`echo ${APP_HOME}/lib/*.zip | tr ' ' ${PATH_SEPARATOR}`${PATH_SEPARATOR}${CLASSPATH}
CLASSPATH=`echo ${ANT_HOME}/lib/*.jar | tr ' ' ${PATH_SEPARATOR}`${PATH_SEPARATOR}${CLASSPATH}
CLASSPATH=`echo ${ANT_HOME}/lib/*.zip | tr ' ' ${PATH_SEPARATOR}`${PATH_SEPARATOR}${CLASSPATH}
CLASSPATH=${APP_HOME}/build/classes${PATH_SEPARATOR}${CLASSPATH}
export CLASSPATH

### load other variables from profile
source /etc/profile #set all env

2. app.sh
#!/bin/sh
# -----------------------------------------------------------------------------
# app.sh - Script to run applications
#
# Environment Variable Prequisites
#
#   APP_HOME (Optional) May point at your APP "build" directory.
#                 If not present, the current working directory is assumed.
#   APP_OPTS (Optional) Java runtime options used when the "start",
#                 "stop", or "run" command is executed.
#   JAVA_HOME     Must point at your Java Development Kit installation.
# -----------------------------------------------------------------------------

# ----- Checking JVM variables -------------------------
export JAVA_PARAM=$1
if [ "$JAVA_PARAM" = "-javaMax" ]
then
    shift
    export memoryX=$1
    shift
else
    export memoryX="1024"
fi

export JAVA_PARAM=$1
if [ "$JAVA_PARAM" = "-jmxHost" ]
then
    shift
    jmxHost=$1
    shift
fi

export JAVA_PARAM=$1
if [ "$JAVA_PARAM" = "-jmxPort" ]
then
    shift
    jmxPort=$1
    shift
fi

# fix env. issues
source /etc/profile

# ----- Verify and Set Required Environment Variables -------------------------
export LANG="en_US.UTF8"

    if [ -z "$APP_HOME" ] ; then
    ## resolve links - $0 may be a link to  home
    PRG=$0
    progname=`basename $0`
	
    while [ -h "$PRG" ] ; do
	ls=`ls -ld "$PRG"`
	link=`expr "$ls" : '.*-> \(.*\)$'`
	    if expr "$link" : '.*/.*' > /dev/null; then
	    PRG="$link"
	else
	    PRG="`dirname $PRG`/$link"
	fi
    done
    
    APP_HOME_1=`dirname "$PRG"`/../..
    echo "Guessing APP_HOME from app.sh to ${APP_HOME_1}" 
	    if [ -d ${APP_HOME_1}/properties ] ; then 
	    APP_HOME=${APP_HOME_1}
	    echo "Setting APP_HOME to $APP_HOME"
	fi
    fi
    
	if [ -z "$APP_OPTS" ] ; then
    APP_OPTS=""
    fi
    
	if [ -z "$JPDA_OPTS" ] ; then
    JPDA_OPTS="-Xdebug -Xnoagent -Xrunjdwp:transport=dt_socket,address=8000,server=y,suspend=n"
    fi
    
	if [ -z "$JAVA_HOME" ] ; then
	echo You must set JAVA_HOME to point at your Java Development Kit installation
	    exit 1
fi
	

# ----- Cygwin Unix Paths Setup -----------------------------------------------

# Cygwin support.  $cygwin _must_ be set to either true or false.
case "`uname`" in
  CYGWIN*) cygwin=true ;;
  *) cygwin=false ;;
esac
 
# For Cygwin, ensure paths are in UNIX format before anything is touched
if $cygwin ; then
  [ -n "$APP_HOME" ] &&
    APP_HOME=`cygpath --unix "$APP_HOME"`
    [ -n "$JAVA_HOME" ] &&
    JAVA_HOME=`cygpath --unix "$JAVA_HOME"`
fi


# ----- Set Up The Classpath -------------------------------------------

CP=${APP_HOME}/build/classes

CP=`echo ${APP_HOME}/lib/*.jar | tr ' ' :`:${CP}
CP=`echo ${APP_HOME}/lib/*.zip | tr ' ' :`:${CP}
if [ -f "$JAVA_HOME/lib/tools.jar" ] ; then
  CP=$CP:"$JAVA_HOME/lib/tools.jar"
fi

# ----- Cygwin Windows Paths Setup --------------------------------------------

# convert the existing path to windows
if $cygwin ; then
   CP=`cygpath --path --windows "$CP"`
   APP_HOME=`cygpath --path --windows "$APP_HOME"`
   JAVA_HOME=`cygpath --path --windows "$JAVA_HOME"`
fi


# ----- Execute The Requested Command -----------------------------------------

echo "Using CLASSPATH:     $CP"
echo "Using APP_HOME: $APP_HOME"
echo "Using JAVA_HOME:     $JAVA_HOME"

JMX_OPTS=""

if [ "$jmxHost" != "" ]
then
    JMX_OPTS=" -Dcom.sun.management.jmxremote.authenticate=false -Dcom.sun.management.jmxremote.ssl=false -Dcom.sun.management.jmxremote -Djava.rmi.server.hostname="$jmxHost
fi

if [ "$jmxPort" != "" ]
then
    JMX_OPTS=$JMX_OPTS" -Dcom.sun.management.jmxremote.port="$jmxPort
fi

export JAVA_OPTS="-verbosegc -XX:+PrintGCDetails -XX:+PrintTenuringDistribution"

JAVA_OPTS=$JAVA_OPTS" "-server" "-Xms256M" "-Xmx$memoryX"M "-XX:NewSize=128m" "-XX:MaxNewSize=128m" "-XX:+UseConcMarkSweepGC" "-Xconcurrentio" "-Xnoclassgc"" 
JAVA_OPTS=$JAVA_OPTS" "$JMX_OPTS

JAVA_OPTS=$JAVA_OPTS" "-Doracle.jdbc.V8Compatible=true

$JAVA_HOME/bin/java ${JAVA_OPTS} $APP_OPTS -classpath $CP -Dapp.base=$APP_BASE  -Dapp.home=$APP_HOME -Djava.library.path=$HOME/JMagick/lib $@

3. runMyJob.sh
#!/bin/sh
#=============================================================================
# Desc   : MyJob
# 00 03 * * * /home/app/src/scripts/runMyJob.sh 0 >> /home/app/runMyJob0.log 2>&1
#=============================================================================

export APP_HOME=$HOME/app
cd $HOME
. .bashrc
cd $APP_HOME
. setupenv.sh

LOCKFILE="$HOME/MyJob$1.lock";
CONCURRENT_WARNING="MyJob lock file found: $LOCKFILE 
Probably a previous job is still executing, please wait for a while and try again later.
"; init_day=`date +%Y%m%d%H%M`; logfile="$HOME/MyJob$1_$init_day.log"; if [ -f $LOCKFILE ] then echo "$CONCURRENT_WARNING"; exit 1; fi #create a lock file to prevent concurrent job requests touch $LOCKFILE echo ">>>>>START at `date`" echo ">>> execute the business ...." $APP_HOME/src/scripts/app.sh -javaMax 2049 com.zdp.MyJob $1 >> $logfile 2>&1 echo ">>> $1 .... " #gzip log file gzip $logfile; #move the log to the logs directory cd $HOME mv $logfile.gz $HOME/logs/ # remove lock file rm -rf $LOCKFILE echo ">>>>> END at `date`"

4.Javaプログラム:MyJob.java
package com.zdp;

public class MyJob {
    private static String MODE = "0";
	public static void main(String args[]) throws Exception {
		try {
			System.out.println("----------------- START -----------------");
			long begin = System.currentTimeMillis();
			if (args.length > 0) {
				MODE = args[0];
			}
			
			// main logic
			
			long end = System.currentTimeMillis();
			System.out.println("<<<<<<<<<<<<<<<<<<<<  Total spent time: " + (end - begin) / 1000 + "s  >>>>>>>>>>>>>>>>>>>>");
			System.out.println("----------------- END -------------------");
		} catch (Exception e) {
			logger.error(e.getMessage(), e); 
			System.exit(1);
		} finally{
			System.exit(0);
		}
	}
	
}

プログラムを直接実行する場合は、次のように呼び出すこともできます.
$app_home/src/scripts/app.sh -javaMax 2049 MyJob >>/home/app/MyJob.log 2>&1