运行 jenkins 中的 akka 应用程序
Running akka app in jenkins
我在 jenkins 中使用播放插件 (https://wiki.jenkins-ci.org/display/JENKINS/play-plugin) in jenkins to clean, compile and build the application, but when I run the application using a managed script (https://wiki.jenkins-ci.org/display/JENKINS/Managed+Script+Plugin),应用程序立即启动和停止,没有任何错误。
有人知道吗?
托管脚本
#!/bin/bash
#
# =========================================================================
# Copyright 2014 Rado Buransky, Dominion Marine Media
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ========================================================================
#
#
# Check this blog post I wrote with detailed information:
# http://buransky.com/play-framework/init-d-shell-script-for-play-framework-distributed-application/
#
#
# Script to start, stop and check status of a Play framework application. It requires
# the Play application to be packaged using the "dist" command. Before you run the script,
# you have to set values of NAME, PORT and APP_DIR variables.
#
# NAME – name of the application, must be the same as the name of shell script
# generated by Play framework to run the app
# PORT – port number at which the app should run
# APP_DIR – path to directory where you have unzipped the packaged app
#
#
# Usage: control.sh {start|stop|status|restart}
# port - requred for start and restart commands
#
# Example: control.sh restart app-name 9000
#
#
# The script uses RUNNING_PID file generated by Play framework which contains ID of the
# application server process.
#
#
# START YOUR APPLICATION WHEN MACHINE STARTS
# ==========================================
#
# The script uses RUNNING_PID file generated by Play framework which contains ID of
# the application server process.
#
#
# SAFE START
# ==========
#
# After starting the application the script checks whether the RUNNING_PID file has
# been created and whether the process is really running. After that it uses wget
# utility to issue an HTTP GET request for root document to do yet another check
# whether the server is alive. Of course this assumes that your application serves
# this document. If you don’t like (or have) wget I have provided curl version for
# your convenience as well.
#
#
# SAFE STOP
# =========
#
# Stop checks whether the process whose ID is in the RUNNING_PID file really belongs
# to your application. This is an important check so that we don’t kill an innocent
# process by accident. Then it sends termination signals to the process starting
# with the most gentle ones until the process dies.
#
#
# Script arguments (start, stop, restart or status)
COMMAND=
# ***********************************************
# ************* Set these variables ***********
NAME=Name
PORT=9001
APP_DIR=PATH
# ***********************************************
# ***********************************************
# Additional arguments to be passed to the Play application
APP_ARGS=-Dhttp.port=${PORT}
# Path to the RUNNING_PID file containing process ID
PID_FILE=$APP_DIR/RUNNING_PID
# Helper functions
echoProgress()
{
setColor 6
printf "%-70s" "..."
resetColor
return 0
}
echoError()
{
setColor 6
#printf "ERROR"
if [ ! -z "" ]
then
resetColor
#printf " []"
fi
printf "\n"
resetColor
return 0
}
echoOK()
{
setColor 2
printf "OK"
if [ ! -z "" ]
then
resetColor
printf " []"
fi
printf "\n"
resetColor
return 0
}
checkResult()
{
if [ "" -ne 0 ]
then
echoError ""
exit 1
fi
}
setColor()
{
tput setaf 2>/dev/null
}
resetColor()
{
tput sgr0 2>/dev/null
}
# Checks if RUNNING_PID file exists and whether the process is really running.
checkPidFile()
{
if [ -f $PID_FILE ]
then
if ps -p `cat $PID_FILE` > /dev/null
then
# The file exists and the process is running
return 1
else
# The file exitsts, but the process is dead
return 2
fi
fi
# The file doesn't exist
return 0
}
# Gently kill the given process
kill_softly()
{
SAFE_CHECK=`ps $@ | grep [-]Duser.dir=$APP_DIR`
if [ -z "$SAFE_CHECK" ]
then
# Process ID doesn't belong to expected application! Don't kill it!
return 1
else
# Send termination signals one by one
for sig in TERM HUP INT QUIT PIPE KILL; do
if ! kill -$sig "$@" > /dev/null 2>&1 ;
then
break
fi
sleep 2
done
fi
}
# Get process ID from RUNNING_PID file and print it
printPid()
{
PID=`cat $PID_FILE`
printf "PID=$PID"
}
# Check port input argument
checkPort()
{
if [ -z "$PORT" ]
then
echoError "Port not set!"
return 1
fi
}
# Check input arguments
checkArgs()
{
# Check command
case "$COMMAND" in
start | stop | restart | status) ;;
*)
echoError "Unknown command"
return 1
;;
esac
# Check application name
if [ -z "$NAME" ]
then
echoError "Application name not set!"
return 1
fi
# Check application directory
if [ -z "$APP_DIR" ]
then
echoError "Application installation directory not set!"
return 1
fi
# Check port
case "$COMMAND" in
start | restart)
checkPort
if [ $? != 0 ]
then
return 1
fi
;;
esac
}
checkAppStarted()
{
# Wait a bit
sleep 3
# Check if RUNNING_PID file exists and if process is really running
checkPidFile
if [ $? != 1 ]
then
echoError
cat $TMP_LOG 1>&2
exit 1
fi
local HTTP_RESPONSE_CODE
# Issue HTTP GET request using wget to check if the app is really started. Of course this
# command assumes that your server supports GET for the root URL.
HTTP_RESPONSE_CODE=`wget -SO- "http://localhost:$PORT/" 2>&1 | grep "HTTP/" | awk '{print }'`
# The same functionality but using curl. For your convenience.
#HTTP_RESPONSE_CODE=`curl --connect-timeout 20 --retry 3 -o /dev/null --silent --write-out "%{http_code}" http://localhost:$PORT/`
checkResult $? "no response from server, timeout"
if [ $HTTP_RESPONSE_CODE != 200 ]
then
echoError "HTTP GET / = $HTTP_RESPONSE_CODE"
exit 1
fi
}
# Check input arguments
checkArgs
if [ $? != 0 ]
then
echo "Usage: [=11=] {start|stop|status|restart}"
exit 1
fi
case "${COMMAND}" in
start)
echoProgress "Starting $NAME at port $PORT"
checkPidFile
case $? in
1) echoOK "$(printPid) already started"
exit ;;
2) # Delete the RUNNING_PID FILE
rm $PID_FILE ;;
esac
SCRIPT_TO_RUN=$APP_DIR/bin/$NAME
if [ ! -f $SCRIPT_TO_RUN ]
then
echoError "Play script doesn't exist!"
exit 1
fi
# * * * Run the Play application * * *
TMP_LOG=`mktemp`
PID=`$SCRIPT_TO_RUN $APP_ARGS > /dev/null 2>$TMP_LOG & echo $!`
# Check if successfully started
if [ $? != 0 ]
then
echoError
exit 1
else
checkAppStarted
echoOK "PID=$PID"
fi
;;
status)
echoProgress "Checking $NAME at port $PORT"
checkPidFile
case $? in
0) echoOK "not running" ;;
1) echoOK "$(printPid) running" ;;
2) echoError "process dead but RUNNING_PID file exists" ;;
esac
;;
stop)
echoProgress "Stopping $NAME"
checkPidFile
case $? in
0) echoOK "wasn't running" ;;
1) PRINTED_PID=$(printPid)
kill_softly `cat $PID_FILE`
if [ $? != 0 ]
then
echoError "$PRINTED_PID doesn't belong to $NAME! Human intervention is required."
exit 1
else
echoOK "$PRINTED_PID stopped"
fi ;;
2) echoError "RUNNING_PID exists but process is already dead" ;;
esac
;;
restart)
[=11=] stop $NAME $PORT
if [ $? == 0 ]
then
[=11=] start $NAME $PORT
if [ $? == 0 ]
then
# Success
exit
fi
fi
exit 1
;;
esac
不是没有看到设置、命令或一些日志文件。这不是直接的答案,但您是否考虑过使用 Maven 运行 应用程序?这适用于 akka 应用程序:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<mainClass>com.yourapp.Hello</mainClass>
</configuration>
</plugin>
编辑以回答更多评论:本机打包程序信息
示例 build.sbt 可能如下所示:
import com.typesafe.sbt.packager.archetypes.ServerLoader.SystemV
scalaVersion := "2.11.7"
val timestamp: Long = System.currentTimeMillis / 1000
name := """my-app"""
maintainer := "Me Me <me@me.io>"
packageName := """my-app"""
packageDescription := "My business logic."
packageSummary := "Test app."
version := s"1.0.0"
name in Universal := name.value
name in UniversalDocs <<= name in Universal
name in UniversalSrc <<= name in Universal
packageName in Universal := packageName.value
serverLoading in Debian := SystemV
...废话
fork in run := true
publishArtifact in(Compile, packageDoc) := false
publishArtifact in packageDoc := false
sources in(Compile, doc) := Seq.empty
enablePlugins {
DebianPlugin
JavaServerAppPackaging
}
这将帮助您使用 sbt debian:packageBin
创建一个本地 Debian 软件包,它可以在机器上(一旦安装)通过 service <servicename> start|stop|restart
进行控制
结果是 jenkins 构建进程杀死了它创建的任何子进程 (https://wiki.jenkins-ci.org/display/JENKINS/ProcessTreeKiller)。
所以为了解决这个问题我不得不添加
export BUILD_ID=dontKillMe
到我想继续的进程(shell 脚本)运行。
我在 jenkins 中使用播放插件 (https://wiki.jenkins-ci.org/display/JENKINS/play-plugin) in jenkins to clean, compile and build the application, but when I run the application using a managed script (https://wiki.jenkins-ci.org/display/JENKINS/Managed+Script+Plugin),应用程序立即启动和停止,没有任何错误。
有人知道吗?
托管脚本
#!/bin/bash
#
# =========================================================================
# Copyright 2014 Rado Buransky, Dominion Marine Media
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ========================================================================
#
#
# Check this blog post I wrote with detailed information:
# http://buransky.com/play-framework/init-d-shell-script-for-play-framework-distributed-application/
#
#
# Script to start, stop and check status of a Play framework application. It requires
# the Play application to be packaged using the "dist" command. Before you run the script,
# you have to set values of NAME, PORT and APP_DIR variables.
#
# NAME – name of the application, must be the same as the name of shell script
# generated by Play framework to run the app
# PORT – port number at which the app should run
# APP_DIR – path to directory where you have unzipped the packaged app
#
#
# Usage: control.sh {start|stop|status|restart}
# port - requred for start and restart commands
#
# Example: control.sh restart app-name 9000
#
#
# The script uses RUNNING_PID file generated by Play framework which contains ID of the
# application server process.
#
#
# START YOUR APPLICATION WHEN MACHINE STARTS
# ==========================================
#
# The script uses RUNNING_PID file generated by Play framework which contains ID of
# the application server process.
#
#
# SAFE START
# ==========
#
# After starting the application the script checks whether the RUNNING_PID file has
# been created and whether the process is really running. After that it uses wget
# utility to issue an HTTP GET request for root document to do yet another check
# whether the server is alive. Of course this assumes that your application serves
# this document. If you don’t like (or have) wget I have provided curl version for
# your convenience as well.
#
#
# SAFE STOP
# =========
#
# Stop checks whether the process whose ID is in the RUNNING_PID file really belongs
# to your application. This is an important check so that we don’t kill an innocent
# process by accident. Then it sends termination signals to the process starting
# with the most gentle ones until the process dies.
#
#
# Script arguments (start, stop, restart or status)
COMMAND=
# ***********************************************
# ************* Set these variables ***********
NAME=Name
PORT=9001
APP_DIR=PATH
# ***********************************************
# ***********************************************
# Additional arguments to be passed to the Play application
APP_ARGS=-Dhttp.port=${PORT}
# Path to the RUNNING_PID file containing process ID
PID_FILE=$APP_DIR/RUNNING_PID
# Helper functions
echoProgress()
{
setColor 6
printf "%-70s" "..."
resetColor
return 0
}
echoError()
{
setColor 6
#printf "ERROR"
if [ ! -z "" ]
then
resetColor
#printf " []"
fi
printf "\n"
resetColor
return 0
}
echoOK()
{
setColor 2
printf "OK"
if [ ! -z "" ]
then
resetColor
printf " []"
fi
printf "\n"
resetColor
return 0
}
checkResult()
{
if [ "" -ne 0 ]
then
echoError ""
exit 1
fi
}
setColor()
{
tput setaf 2>/dev/null
}
resetColor()
{
tput sgr0 2>/dev/null
}
# Checks if RUNNING_PID file exists and whether the process is really running.
checkPidFile()
{
if [ -f $PID_FILE ]
then
if ps -p `cat $PID_FILE` > /dev/null
then
# The file exists and the process is running
return 1
else
# The file exitsts, but the process is dead
return 2
fi
fi
# The file doesn't exist
return 0
}
# Gently kill the given process
kill_softly()
{
SAFE_CHECK=`ps $@ | grep [-]Duser.dir=$APP_DIR`
if [ -z "$SAFE_CHECK" ]
then
# Process ID doesn't belong to expected application! Don't kill it!
return 1
else
# Send termination signals one by one
for sig in TERM HUP INT QUIT PIPE KILL; do
if ! kill -$sig "$@" > /dev/null 2>&1 ;
then
break
fi
sleep 2
done
fi
}
# Get process ID from RUNNING_PID file and print it
printPid()
{
PID=`cat $PID_FILE`
printf "PID=$PID"
}
# Check port input argument
checkPort()
{
if [ -z "$PORT" ]
then
echoError "Port not set!"
return 1
fi
}
# Check input arguments
checkArgs()
{
# Check command
case "$COMMAND" in
start | stop | restart | status) ;;
*)
echoError "Unknown command"
return 1
;;
esac
# Check application name
if [ -z "$NAME" ]
then
echoError "Application name not set!"
return 1
fi
# Check application directory
if [ -z "$APP_DIR" ]
then
echoError "Application installation directory not set!"
return 1
fi
# Check port
case "$COMMAND" in
start | restart)
checkPort
if [ $? != 0 ]
then
return 1
fi
;;
esac
}
checkAppStarted()
{
# Wait a bit
sleep 3
# Check if RUNNING_PID file exists and if process is really running
checkPidFile
if [ $? != 1 ]
then
echoError
cat $TMP_LOG 1>&2
exit 1
fi
local HTTP_RESPONSE_CODE
# Issue HTTP GET request using wget to check if the app is really started. Of course this
# command assumes that your server supports GET for the root URL.
HTTP_RESPONSE_CODE=`wget -SO- "http://localhost:$PORT/" 2>&1 | grep "HTTP/" | awk '{print }'`
# The same functionality but using curl. For your convenience.
#HTTP_RESPONSE_CODE=`curl --connect-timeout 20 --retry 3 -o /dev/null --silent --write-out "%{http_code}" http://localhost:$PORT/`
checkResult $? "no response from server, timeout"
if [ $HTTP_RESPONSE_CODE != 200 ]
then
echoError "HTTP GET / = $HTTP_RESPONSE_CODE"
exit 1
fi
}
# Check input arguments
checkArgs
if [ $? != 0 ]
then
echo "Usage: [=11=] {start|stop|status|restart}"
exit 1
fi
case "${COMMAND}" in
start)
echoProgress "Starting $NAME at port $PORT"
checkPidFile
case $? in
1) echoOK "$(printPid) already started"
exit ;;
2) # Delete the RUNNING_PID FILE
rm $PID_FILE ;;
esac
SCRIPT_TO_RUN=$APP_DIR/bin/$NAME
if [ ! -f $SCRIPT_TO_RUN ]
then
echoError "Play script doesn't exist!"
exit 1
fi
# * * * Run the Play application * * *
TMP_LOG=`mktemp`
PID=`$SCRIPT_TO_RUN $APP_ARGS > /dev/null 2>$TMP_LOG & echo $!`
# Check if successfully started
if [ $? != 0 ]
then
echoError
exit 1
else
checkAppStarted
echoOK "PID=$PID"
fi
;;
status)
echoProgress "Checking $NAME at port $PORT"
checkPidFile
case $? in
0) echoOK "not running" ;;
1) echoOK "$(printPid) running" ;;
2) echoError "process dead but RUNNING_PID file exists" ;;
esac
;;
stop)
echoProgress "Stopping $NAME"
checkPidFile
case $? in
0) echoOK "wasn't running" ;;
1) PRINTED_PID=$(printPid)
kill_softly `cat $PID_FILE`
if [ $? != 0 ]
then
echoError "$PRINTED_PID doesn't belong to $NAME! Human intervention is required."
exit 1
else
echoOK "$PRINTED_PID stopped"
fi ;;
2) echoError "RUNNING_PID exists but process is already dead" ;;
esac
;;
restart)
[=11=] stop $NAME $PORT
if [ $? == 0 ]
then
[=11=] start $NAME $PORT
if [ $? == 0 ]
then
# Success
exit
fi
fi
exit 1
;;
esac
不是没有看到设置、命令或一些日志文件。这不是直接的答案,但您是否考虑过使用 Maven 运行 应用程序?这适用于 akka 应用程序:
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>exec-maven-plugin</artifactId>
<version>1.2.1</version>
<configuration>
<mainClass>com.yourapp.Hello</mainClass>
</configuration>
</plugin>
编辑以回答更多评论:本机打包程序信息
示例 build.sbt 可能如下所示:
import com.typesafe.sbt.packager.archetypes.ServerLoader.SystemV
scalaVersion := "2.11.7"
val timestamp: Long = System.currentTimeMillis / 1000
name := """my-app"""
maintainer := "Me Me <me@me.io>"
packageName := """my-app"""
packageDescription := "My business logic."
packageSummary := "Test app."
version := s"1.0.0"
name in Universal := name.value
name in UniversalDocs <<= name in Universal
name in UniversalSrc <<= name in Universal
packageName in Universal := packageName.value
serverLoading in Debian := SystemV
...废话
fork in run := true
publishArtifact in(Compile, packageDoc) := false
publishArtifact in packageDoc := false
sources in(Compile, doc) := Seq.empty
enablePlugins {
DebianPlugin
JavaServerAppPackaging
}
这将帮助您使用 sbt debian:packageBin
创建一个本地 Debian 软件包,它可以在机器上(一旦安装)通过 service <servicename> start|stop|restart
结果是 jenkins 构建进程杀死了它创建的任何子进程 (https://wiki.jenkins-ci.org/display/JENKINS/ProcessTreeKiller)。
所以为了解决这个问题我不得不添加
export BUILD_ID=dontKillMe
到我想继续的进程(shell 脚本)运行。