Jenkins+Maven+Git 自动部署 Java 应用(安装)

Anton Chen | 2016-02-23

Jenkins+Maven+Git 自动部署 Java 应用(安装)
Jenkins+Maven+Git 自动部署 Java 应用(配置)
Jenkins+Maven+Git 自动部署 Java 应用(编译)

介绍

Jenkins 是基于 Java 开发的一种持续集成工具,然而我并不知道持续集成是个什么鬼。总之 Jenkins 可以用来做自动化构建,同时包括编译、发布、自动化测试。 本文写只是讲解如何通过 Jenkins 来做自动化构建与发布,即自动化升级。

以上全是胡说八道当不得真

环境

开发环境

  • Maven 项目管理
  • Git 版本管理
  • log4j 日志输出

Jenkins 环境

  • CentOS 6.x x64
  • 1 核心 1G 内存以上空闲资源
  • JDK 7u80
  • Maven 3.3.9
  • jenkins.war 1.642.1 LTS

下载地址

安装

系统调优略过

依赖

安装必要依赖以及工具

yum install -y wget unzip git

JDK

下载解压 JDK

cd /data/working
wget -c http://download.oracle.com/otn/java/jdk/7u80-b15/jdk-7u80-linux-x64.tar.gz
mkdir /application
cd /application
tar xf /data/working/jdk-7u80-linux-x64.tar.gz
ln -s jdk1.7.0_80 jdk
cd ~

配置 JDK 环境变量

cat >> /etc/profile <<_JDK_
export JAVA_HOME=/application/jdk
export CLASSPATH=.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$JAVA_HOME/bin:$PATH
_JDK_
source /etc/profile

检查 JDK

java -version

结果

java version "1.7.0_80"
Java(TM) SE Runtime Environment (build 1.7.0_80-b15)
Java HotSpot(TM) 64-Bit Server VM (build 24.80-b11, mixed mode)

Maven

下载解压 Maven

cd /data/working
wget -c http://mirrors.noc.im/apache/maven/maven-3/3.3.9/binaries/apache-maven-3.3.9-bin.zip
cd /application
unzip /data/working/apache-maven-3.3.9-bin.zip
mv apache-maven-3.3.9 maven-3.3.9
ln -s maven-3.3.9 maven
cd ~

配置 Maven 环境变量

sed -i 's#export PATH=#&\/application/maven/bin:#' /etc/profile
source /etc/profile

检查 Maven

mvn -v

结果

Apache Maven 3.3.9 (bb52d8502b132ec0a5a3f4c09453c07478323dc5; 2015-11-11T00:41:47+08:00)
Maven home: /application/maven
Java version: 1.7.0_80, vendor: Oracle Corporation
Java home: /application/jdk1.7.0_80/jre
Default locale: en_US, platform encoding: UTF-8
OS name: "linux", version: "2.6.32-573.12.1.el6.x86_64", arch: "amd64", family: "unix"

Jenkins

下载 Jenkins

cd /data/working
wget -c http://mirrors.jenkins-ci.org/war-stable/latest/jenkins.war
cd /application
mkdir jenkins-1.642.1
ln -s jenkins-1.642.1 jenkins
cp /data/working/jenkins.war jenkins/
cd ~

创建 Jenkins 运行账户,设置对应权限

useradd -u 600 jenkins -d /application/jenkins
chown -R jenkins:jenkins /application/jenkins*

创建 Jenkins 需要的目录,设置对应权限

mkdir -p /data/pid /data/jenkins/{logs,war,data}
chown -R jenkins:jenkins /data/jenkins
chmod 777 /data/pid

创建配置文件

## Path:        Development/Jenkins
## Description: Jenkins Continuous Integration Server
## Type:        string
## Default:     "/var/lib/jenkins"
## ServiceRestart: jenkins
#
# Directory where Jenkins store its configuration and working
# files (checkouts, build reports, artifacts, ...).
# 数据存储目录,包括之后的项目源码,项目编译结果
JENKINS_HOME="/data/jenkins/data"

## Type:        string
## Default:     "jenkins"
## ServiceRestart: jenkins
#
# Unix user account that runs the Jenkins daemon
# Be careful when you change this, as you need to update
# permissions of $JENKINS_HOME and /var/log/jenkins.
# 运行Jenkins的账户,需要自己建立
JENKINS_USER="jenkins"

## Type:        string
## Default: "false"
## ServiceRestart: jenkins
#
# Whether to skip potentially long-running chown at the
# $JENKINS_HOME location. Do not enable this, "true", unless
# you know what you're doing. See JENKINS-23273.
#
#JENKINS_INSTALL_SKIP_CHOWN="false"

## Type: string
## Default:     "-Djava.awt.headless=true"
## ServiceRestart: jenkins
#
# Options to pass to java when running Jenkins.
#
JENKINS_JAVA_OPTIONS="-Djava.awt.headless=true"

## Type:        integer(0:65535)
## Default:     8080
## ServiceRestart: jenkins
#
# Port Jenkins is listening on.
# Set to -1 to disable
# 服务端口
JENKINS_PORT="8080"

## Type:        string
## Default:     ""
## ServiceRestart: jenkins
#
# IP address Jenkins listens on for HTTP requests.
# Default is all interfaces (0.0.0.0).
#
JENKINS_LISTEN_ADDRESS=""

## Type:        integer(0:65535)
## Default:     ""
## ServiceRestart: jenkins
#
# HTTPS port Jenkins is listening on.
# Default is disabled.
#
JENKINS_HTTPS_PORT=""

## Type:        string
## Default:     ""
## ServiceRestart: jenkins
#
# Path to the keystore in JKS format (as created by the JDK 'keytool').
# Default is disabled.
#
JENKINS_HTTPS_KEYSTORE=""

## Type:        string
## Default:     ""
## ServiceRestart: jenkins
#
# Password to access the keystore defined in JENKINS_HTTPS_KEYSTORE.
# Default is disabled.
#
JENKINS_HTTPS_KEYSTORE_PASSWORD=""

## Type:        string
## Default:     ""
## ServiceRestart: jenkins
#
# IP address Jenkins listens on for HTTPS requests.
# Default is disabled.
#
JENKINS_HTTPS_LISTEN_ADDRESS=""

## Type:        integer(0:65535)
## Default:     8009
## ServiceRestart: jenkins
#
# Ajp13 Port Jenkins is listening on.
# Set to -1 to disable
#
JENKINS_AJP_PORT="8009"

## Type:        string
## Default:     ""
## ServiceRestart: jenkins
#
# IP address Jenkins listens on for Ajp13 requests.
# Default is all interfaces (0.0.0.0).
#
JENKINS_AJP_LISTEN_ADDRESS=""

## Type:        integer(1:9)
## Default:     5
## ServiceRestart: jenkins
#
# Debug level for logs -- the higher the value, the more verbose.
# 5 is INFO.
#
JENKINS_DEBUG_LEVEL="5"

## Type:        yesno
## Default:     no
## ServiceRestart: jenkins
#
# Whether to enable access logging or not.
#
JENKINS_ENABLE_ACCESS_LOG="no"

## Type:        integer
## Default:     100
## ServiceRestart: jenkins
#
# Maximum number of HTTP worker threads.
#
JENKINS_HANDLER_MAX="100"

## Type:        integer
## Default:     20
## ServiceRestart: jenkins
#
# Maximum number of idle HTTP worker threads.
#
JENKINS_HANDLER_IDLE="20"

## Type:        string
## Default:     ""
## ServiceRestart: jenkins
#
# Pass arbitrary arguments to Jenkins.
# Full option list: java -jar jenkins.war --help
#
JENKINS_ARGS=""

创建 Jenkins 启动脚本

#!/bin/bash
# File: /etc/init.d/jenkins
# Usage: /etc/init.d/jenkins
# chkconfig: 2345 57 46
# Description: Jenkins Continuous Integration Server.
# Version: 0.1
# Create Date: 2016-02-23 15:31
# Modified: 2016-02-23 15:31
# Author: Anton Chen
# Author EMail: contact@antonchen.com
. /etc/init.d/functions
# Read config
serviceConf="/application/jenkins/jenkins.conf"
if [ -f $serviceConf ];then
    . $serviceConf
else
   JENKINS_USER="jenkins"
fi

serviceName="Jenkins"
serviceUser="$JENKINS_USER"
javaExec="/application/jdk/bin/java"
serviceExec="/application/jenkins/jenkins.war"
servicePid="/data/pid/jenkins.pid"
serviceLogs="/data/jenkins/logs/jenkins.log"
accessLogs="/data/jenkins/logs/access.log"
jenkinsWebRoot="/data/jenkins/war"

# Check All
[ -f $javaExec ] || { echo "Java Exec not existing."; exit 1; }
[ -f $serviceExec ] || { echo "$serviceName Exec not existing."; exit 1; }
[ -d $jenkinsWebRoot ] || { echo "Jenkins Web directory not existing."; exit 1; }

# Set runCmd
runCmd="$javaExec $JENKINS_JAVA_OPTIONS -DJENKINS_HOME=$JENKINS_HOME -Dhudson.DNSMultiCast.disabled=true -jar $serviceExec"

# Load Jenkins config
runOpt="--logfile=$serviceLogs --webroot=$jenkinsWebRoot --daemon"
[ -n "$JENKINS_PORT" ] && runOpt="$runOpt --httpPort=$JENKINS_PORT"
[ -n "$JENKINS_LISTEN_ADDRESS" ] && runOpt="$runOpt --httpListenAddress=$JENKINS_LISTEN_ADDRESS"
[ -n "$JENKINS_HTTPS_PORT" ] && runOpt="$runOpt --httpsPort=$JENKINS_HTTPS_PORT"
[ -n "$JENKINS_HTTPS_KEYSTORE" ] && runOpt="$runOpt --httpsKeyStore=$JENKINS_HTTPS_KEYSTORE"
[ -n "$JENKINS_HTTPS_KEYSTORE_PASSWORD" ] && runOpt="$runOpt --httpsKeyStorePassword='$JENKINS_HTTPS_KEYSTORE_PASSWORD'"
[ -n "$JENKINS_HTTPS_LISTEN_ADDRESS" ] && runOpt="$runOpt --httpsListenAddress=$JENKINS_HTTPS_LISTEN_ADDRESS"
[ -n "$JENKINS_AJP_PORT" ] && runOpt="$runOpt --ajp13Port=$JENKINS_AJP_PORT"
[ -n "$JENKINS_AJP_LISTEN_ADDRESS" ] && runOpt="$runOpt --ajp13ListenAddress=$JENKINS_AJP_LISTEN_ADDRESS"
[ -n "$JENKINS_DEBUG_LEVEL" ] && runOpt="$runOpt --debug=$JENKINS_DEBUG_LEVEL"
[ -n "$JENKINS_HANDLER_STARTUP" ] && runOpt="$runOpt --handlerCountStartup=$JENKINS_HANDLER_STARTUP"
[ -n "$JENKINS_HANDLER_MAX" ] && runOpt="$runOpt --handlerCountMax=$JENKINS_HANDLER_MAX"
[ -n "$JENKINS_HANDLER_IDLE" ] && runOpt="$runOpt --handlerCountMaxIdle=$JENKINS_HANDLER_IDLE"
[ -n "$JENKINS_ARGS" ] && runOpt="$runOpt $JENKINS_ARGS"

if [ "$JENKINS_ENABLE_ACCESS_LOG" = "yes" ]; then
    runOpt="$runOpt --accessLoggerClassName=winstone.accesslog.SimpleAccessLogger --simpleAccessLogger.format=combined --simpleAccessLogger.file=$accessLogs"
fi

loading ()
{
    i=0
    while (( $i<$1 ));do
        printf "."
        sleep 1
        i=$(($i+1))
    done
}

checkPid ()
{
    pidFile="$servicePid"
    if [ -f "$pidFile" ]; then
        kill -0 `cat $pidFile` >/dev/null 2>&1
        if [ $? -eq 0 ]; then
            return 0
        else
            return 1
        fi
    else
        return 1
    fi
}

start ()
{
    checkPid
    if [ $? -eq 0 ]; then
        echo "$serviceName is runing."
    else
        printf "Start $serviceName"
        daemon --user "$serviceUser" $runCmd $runOpt > /dev/null
        RETVAL=$?
        loading 2
        if [ $RETVAL -eq 0 ]; then
            # !!!!! Check grep !!!!!
            ps hww -u "$serviceUser" -o ppid,pid,cmd|grep -i "$serviceName"|\
            while read ppid pid cmd; do
                [ "$ppid" = 1 ] || continue
                [ "z$pid" == "z" ] && continue
                echo $pid >$servicePid
            done
            checkPid
            RETVAL=$?
            if [ $RETVAL -eq 0 ]; then
                success
            else
                failure
            fi
        else
            failure
        fi
        echo
    fi
}

stop ()
{
    checkPid
    if [ $? -eq 0 ]; then
        printf "Shutting down $serviceName"
        kill -15 `cat $servicePid`
        loading 2
        checkPid
        if [ $? -eq 0 ]; then
            failure
        else
            success
            rm -f $servicePid
        fi
        echo
    else
	    echo "$serviceName is not runing."
    fi
}

status ()
{
    checkPid
    if [ $? -eq 0 ]; then
        echo "$serviceName is runing,PID = `cat $servicePid`."
    else
        echo "$serviceName is not runing."
    fi
}


case $1 in
    start)
        start
        ;;
    stop)
        stop
        ;;
    status)
        status
        ;;
    restart)
        stop
        start
        ;;
    *)
        echo "Usage: $0 {start|stop|status|restart}"
        exit 1
        ;;
esac

添加 Jenkins 到开机启动

chkconfig --add jenkins

启动 Jenkins

/etc/init.d/jenkins start

访问 http://IP:8080 检查

安装到此结束

修订记录

  • 2016年2月25日
  • Anton Chen
    • 修正启动脚本配置文件不存在,无用户变量问题
    • 修正 JENKINS_HOME 设置
    • 添加配置文件注释
    • 添加系列 URL