前言(废话)

最近公司有个老项目需要做二开,拿到手一看JSP,有点东西,简单熟悉了下代码,过了个需求,开发开始。开发过程中发现这个项目既然没配Jenkins,手动发版,太麻烦了,也费时间,于是当天晚上就把Jenkins发布给安排上了。
废话不多说,直接开搞。

前提条件

  1. 确保Jenkins已安装Publish Over SSH插件
    用于把构建好的war包发送到目标远程服务器中、在远程服务器中执行命令。
  2. 使用Git需要安装Git插件,使用svn就要安装Subversion插件

发布步骤

  1. 先在系统管理中->系统设置中增加SSH Server

    Name:名字
    Hostname:目标服务器Ip
    Username:登录用户名
    Remote Directory:连接到远程服务器哪个目录
    Password:密码(使用密码就勾选Use password authentication)
    其他设置根据情况选填即可
    填写完成点击Test Configuration提示“Success”表示可以连接上远程服务器
    点击保存
  2. 新建一个项目,输入项目名称,选择“构建一个Maven项目”

    点击OK
  3. 配置源码管理

    我这以svn演示,git大同小异
    Repository URL:项目svn地址
    Credentials:svn凭证
    Local module directory:指定签出此模块的本地目录(相对于工作区根目录)。如果为空,URL的最后一个路径名将被用作默认值,就像svn CLI一样。使用单个“.”可用于将项目直接签出到工作区中。
    Repository depth:和svn差不多直接选择infinity(递归所有文件及文件夹) 即可
    Ignore externals:选项将与svn checkout, svn update命令一起使用,以禁用外部定义处理
    Check-out Strategy:签出策略,选择的是尽可能使用svn更新
    高级部分一般不用配置,根据具体情况选择配置
  4. 配置Build

    Root POM:根Pom位置(相对于模块根目录),如果为空,则默认为pom.xml
    Goals and options:指定要执行的目标,例如“clean install”或“deploy”。该字段还可以接受Maven的任何其他命令行选项,如"-e"或"-DskipTests=true"。
    高级部分一般不用配置,根据具体情况选择配置
  5. 配置Post Steps(关键部分
    Add post-build setp选择Send files or execute commands over SSH

    Run only if build succeeds:只有在构建成功时才运行(一般选这个即可)、Run only if build succeeds or is unstable:只有在构建成功或不稳定时才运行 、 Run regardless of build result:不管构建结果如何都运行
    Name:目标服务器(刚刚在系统配置中加的目标服务器)
    Source files:需要上传到服务器的文件。这个字符串是一个用逗号分隔的包含列表,用于一个Ant文件集,例如。**/*.jar 。此文件集的基本目录是工作区。
    Remove prefix:发送到目标服务器要删除的父目录
    Remote directory:目标服务器目录(相对系统配置中的Remote Directory)
    Exec command:要在远程服务器上执行的命令
    此命令将在任何文件传输完成后在远程服务器上执行。
    SSH传输集必须包括源文件模式、Exec命令或两者。如果两者都存在,则在执行命令前先传输文件。如果您想在文件传输之前执行,使用2个传输集,并将Exec命令移动到包含源文件模式的传输集之前。
    下面的命令只做一个参考,具体项目依葫芦画瓢即可。
cd /data/ekpew/ekp.war/bin/

./kill.sh
./kill.sh
./kill.sh

echo kill success 

\cp /data/ekpew/ekp.war/ekp/webapp/upload/*  /a/ -rf

echo back image success 

rm -rf   /data/ekpew/ekp.war

echo rm dir success

cd /data/ekpew/

tar -xvf  ekp.tar.gz

sleep 2s

cd /data/ekpew/ekp.war/bin/

echo startdev.......ing 

#./startdev.sh
./startuat.sh

echo success start app

\cp /a/*  /data/ekpew/ekp.war/ekp/webapp/upload/ -rf

echo recover upload success!!!!
  1. 文中提到的kill.sh其实就是杀应用进程的命令,startuat.sh是启动应用的命令。具体内容看后面的“参考命令”
    最后点击保存。
  2. 最后点击立即构建即可。点击Console Output可查看执行日志。

    提示Success成功,大功告成。

参考命令

以下命令仅供参考,可能不完整,不同应用场景自行diy

kill.sh:

#!/bin/bash
SERVER_PORT=`sed '/server.port/!d;s/.*=//' serverInfo.properties | tr -d '\r'`
APP_NAME=`sed '/app.war.name/!d;s/.*=//' serverInfo.properties | tr -d '\r'`

tpid=`ps -ef|grep $APP_NAME|grep -v grep|grep -v kill|awk '{print $2}'`
if [ ${tpid} ]; then
    echo 'Kill Process!'
    kill -9 $tpid
fi

startuat.sh:

#!/bin/bash

cd `dirname $0`
BIN_DIR=`pwd`

SERVER_PORT=`sed '/server.port/!d;s/.*=//' serverInfo.properties | tr -d '\r'`
APP_NAME=`sed '/app.war.name/!d;s/.*=//' serverInfo.properties | tr -d '\r'`

PIDS=`ps -ef|grep $APP_NAME|grep -v grep|grep -v kill|awk '{print $2}'`

if [ -n "$PIDS" ]; then
    echo "ERROR: The $APP_NAME already started!"
    echo "PID: $PIDS"
    exit 1
fi

if [ -n "$SERVER_PORT" ]; then
    SERVER_PORT_COUNT=`netstat -tln | grep $SERVER_PORT | wc -l`
    if [ $SERVER_PORT_COUNT -gt 0 ]; then
        echo "ERROR: The $APP_NAME port $SERVER_PORT already used!"
        exit 1
    fi
fi

cd ..
DEPLOY_DIR=`pwd`
LOGS_DIR=$DEPLOY_DIR/logs

if [ ! -d $LOGS_DIR ]; then
    mkdir $LOGS_DIR
fi

STDOUT_FILE=$LOGS_DIR/stdout.log

rm -f tpid

JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8"
JAVA_MEM_OPTS="-server -Xmx2g -Xms2g -Xmn256m -XX:+DisableExplicitGC -XX:+UseConcMarkSweepGC -XX:+CMSParallelRemarkEnabled -XX:+UseCMSCompactAtFullCollection -XX:LargePageSizeInBytes=128m -XX:+UseFastAccessorMethods -XX:+UseCMSInitiatingOccupancyOnly -XX:CMSInitiatingOccupancyFraction=70 "

echo -e "Starting the $APP_NAME ...ing\c"

echo $CLASSPATH:./${APP_NAME}/webapp/WEB-INF/classes:./${APP_NAME}/webapp/WEB-INF/lib/*

nohup java $JAVA_OPTS $JAVA_MEM_OPTS -Dspring.profiles.active=uat -classpath $CLASSPATH:./${APP_NAME}/webapp/WEB-INF/classes:./${APP_NAME}/webapp/WEB-INF/lib/* com.yulong.ew.Application >  $STDOUT_FILE 2>&1 &

COUNT=0
while [ $COUNT -lt 1 ]; do    
    echo -e ".\c"
    sleep 1 
    if [ -n "$SERVER_PORT" ]; then
        COUNT=`netstat -an | grep $SERVER_PORT | wc -l`
    else
    	COUNT=`ps -f | grep java | grep "$DEPLOY_DIR" | awk '{print $2}' | wc -l`
    fi
    if [ $COUNT -gt 0 ]; then
        break
    fi
done

echo $! > tpid

echo Start Success!

serverInfo.properties:

##START-SERVER-PORT##
server.port=8080
##END-SERVER-PORT##
##START-APP-WAR-NAME##
app.war.name=ekp
##END-APP-WAR-NAME##

总结

对于经常要迭代的项目,使用Jenkins构建发布项目,释放双手不要太爽。

构建过程:

  1. 拉取最新代码
  2. 打包编译代码
  3. 将打包好的项目发送至目标远程服务器
  4. 执行命令杀死已经启动的应用
  5. 执行命令启用最新打包好的应用

文中只是简单介绍基本使用,Jenkins功能非常强大,提供超过1000个插件来支持构建、部署、自动化, 满足任何项目的需要。