作为一名java开发,目前基本都是windows上开发应用,linux上部署发布应用。
关于发布,一般都是本地手动打包,使用ftp工具上传linux服务器,然后使用命令行启动应用。对于频繁发布的情况,手动发布会浪费大量时间,而且手动打包针对不同环境(dev,sit,uat,pro)容易造成配置文件搞错导致发布出问题,其中带来的负面影响可能更大。而且针对大型的分布式系统,此问题尤为突出,每日新提交的代码本就可能导致系统异常,再因为发布问题,则版本的质量和稳定性都将难以控制。
持续集成就可以解决上述描述的问题,自动构建发布,并且可以定时构建,节省手动发布时间成本及避免人工打包出错,同时及时发现系统开发集成过程中产生的问题。
Jenkins是个开源免费的持续集成工具,有很多插件支持扩展,功能强大。前段时间项目的测试环境jenkins服务器被回收,项目发布又回到了手动发布的原始时代,习惯了点一下发布,猛地还有点不习惯。于是乎了解下jenkins的安装和使用,现整理如下。

Jenkins安装

jenkins官网上支持多种安装方式,选择一个熟悉的方式-war包安装。
在线文档:https://www.jenkins.io/zh/doc/book/installing/
机器上需要先安装配置jdk

jdk安装配置

jdk需要先安装配置,否则无法启动jenkins…
解压后配置环境变量,编辑/etc/profile

  1. vim /etc/profile
  2. shift+G(移动到文件末尾)
  3. 加入配置信息
export JAVA_HOME=/usr/local/software/java/jdk1.8.0_191
export CLASSPATH=.:$JAVA_HOME/jre/lib/rt.jar:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH=$PATH:$JAVA_HOME/bin
  1. 刷新环境变量 source /etc/profile
下载并安装jenkins

1.下载jenkins.war:wget http://mirror.serverion.com/jenkins/war-stable/2.222.3/jenkins.war

2.启动:nohup java -jar jenkins.war & 启动完成后 后台会打印一段用户首次登陆的信息:

jenkins 向另一个jenkins发送消息_Jenkins

3.登陆 输入上述打印的密码,然后开始进行插件安装,有两个选项,推荐安装和自定义。首次使用我选择了推荐安装,后面需要什么插件再自行安装。

Jenkins配置及插件安装

安装完成后,还需要配置并安装一些插件,才可以进行Java maven应用的构建
前置条件:本机先安装并配置jdk,maven,git(svn)。
也可以使用jenkins的自动安装。

插件安装

Jenkins -> 系统管理 -> 插件管理 -> 可选插件 搜索响应插件安装,安装完成需要重启,可勾选自动重启
Maven Integration plugin:支持创建maven项目
publish-over-ssh:用于ssh传输,远程发布需要
Role-based Authorization Strategy:权限配置
Locale plugin
Localization Support Plugin
Localization: Chinese (Simplified):以上三个用于汉化

maven安装

同jdk安装,解压后配置环境变量
配置信息

export MAVEN_HOME=/usr/local/maven/apache-maven-3.6.3
export PATH=$MAVEN_HOME/bin:$PATH
git安装

1.下载git https://github.com/git/git/releases 下载 改后缀为 .tar.gz 并解压,进入解压目录
2.先安装依赖yum install curl-devel expat-devel gettext-devel openssl-devel zlib-devel gcc perl-ExtUtils-MakeMaker
3.如果已安装git 先卸载 yum remove git
4.编译git源码 make prefix=/usr/local/git all
5.安装git make prefix=/usr/local/git install
6.配置环境变量 vim /etc/profile , 底部加入然后重新加载source /etc/profile

PATH=$PATH:/usr/local/git/bin
export PATH

7.检查 git --version

jenkins配置jdk,maven,git

Jenkins -> 系统管理 -> 全局工具配置

jenkins 向另一个jenkins发送消息_java_02


jenkins 向另一个jenkins发送消息_Jenkins_03

jenkins配置远程服务器

Jenkins -> 系统管理 -> 系统配置 -> Publish over SSH
配置远程服务器指的是需要发布应用的目标服务器,本机构建完应用生成jar包后jenkins会根据配置拷贝jar包到远程服务器指定目录
点击新增输入服务器信息,输入完毕后点击高级,输入密码保存即可

Jenkins创建任务

创建任务

1.创建maven项目
2.源码管理 选择Git 输入仓库URL 选择/配置用户名密码 ,指定分支
3.Build中输入构建选项 如 “clean package -Dmaven.test.skip=true”
4.Post Steps(后置步骤) 中 选择 “send files or execute commands over SSH”
选择远程服务器并配置
Source files:**/*.jar
Remove prefix: target
Remote directory:/home
Exec comman:

cd /home
source /etc/profile
/bin/sh run.sh xxx.jar

说明及注意事项:
1.若构建的任务依赖其他任务,选择前置构建步骤并输入所依赖任务,选择锁定
2.第4步为指定构建的jar包并指定远端目录(远端目录即可以在此配置也可以在远程服务器处配置,最终会合并处一个远程目录地址),Exec comman为最终需要执行的shell脚本,jar包复制到远端后,需要启动,可以在此处直接输入启动命令,也可以使用预先保存的脚本启动,执行前source /etc/profile确保java等命令可以执行。
3.-pl xxx -am clean package 可以构建关联的依赖应用

启动脚本

run.sh

#!/bin/sh

###
# linux自启动jar包脚本
# 支持start|restart|stop|status|null,默认restart
# start进程不存在才会启动
# restart进程不存在直接启动,存在先kill再启动
# stop进程存在才杀死
# status进程是否存在
# 为空则执行restart
###
jarname=$1;
pid='';

function findPid() {
	pid=`ps -ef|grep $jarname | grep -v grep| grep -v /bin/sh|awk '{print $2}'`;
}

function start() {
	if [ ! -n "$pid" ]; then
		run;
		
	else
		echo "$jarname already started"
	fi
}

function restart() {
	if [ ! -n "$pid" ]; then
		echo "$jarname pid is not exist"
		run;
		
	else
		echo "$jarname already started, kill pid is $pid"
		kill -9 $pid
		findPid;
		
		if [ ! -n "$pid" ]; then
			run;
		else
			echo "$jarname pid can not killed, start failed"
		fi
	fi
}

function run() {
	echo "$jarname is start..."
	nohup java -Xms128m -Xmx512m -jar $jarname >$jarname.log 2>&1 &
	sleep 1
	findPid;
	echo "$jarname start finish, pid is $pid"
}

function status(){
	if [ ! -n "$pid" ]; then
		echo "$jarname pid is not exist"
	else
		echo "$jarname already started, pid is $pid"
	fi
}

function stop() {
	if [ ! -n "$pid" ]; then
		echo "$jarname pid is not exist"
	else
		echo "$jarname already started, kill pid is $pid"
		kill -9 $pid
		findPid;
		
		if [ ! -n "$pid" ]; then
			echo "$jarname killed success."
		else
			echo "$jarname killed failed."
		fi
	fi
}

findPid;
if [ ! -n "$jarname" ]; then
	echo "jar package name must be specified";
else
	case $2 in
		start) 
			start
		;;
		stop)
			stop
		;;
		status)
			status
		;;
		*)
			echo "support:start|restart|stop|status|null, default is restart"
			restart
		;;
	esac
fi;
exit 0
启动脚本增强版,带备份

run.sh

#!/bin/sh
###
# linux自启动jar包脚本
# 支持start|restart|stop|status|null,默认restart
# start进程不存在才会启动
# restart进程不存在直接启动,存在先kill再启动
# stop进程存在才杀死
# status进程是否存在
# 为空则执行restart
###
jarname=$1;
pid='';

function backFile() {
	backfilename=${jarname%%.jar*}_$(date "+%Y%m%d%H%M%S").jar;
	echo "开始备份";
	cp $jarname ./backFiles/${backfilename};
	echo "备份完成:`pwd`/backFiles/${backfilename}";
}

function isSuccess() {
	sleep 8;
	findPid;
	if [ ! -n "$pid" ]; then
		echo "$jarname start failed"
	else
		echo "$jarname start success"
	fi
}

function findPid() {
	pid=`ps -ef|grep $jarname | grep -v grep| grep -v /bin/sh|awk '{print $2}'`;
}

function start() {
	if [ ! -n "$pid" ]; then
		run;
		
	else
		echo "$jarname already started"
	fi
}

function restart() {
	if [ ! -n "$pid" ]; then
		echo "$jarname pid is not exist"
		run;
		
	else
		echo "$jarname already started, kill pid is $pid"
		kill -9 $pid
		findPid;
		
		if [ ! -n "$pid" ]; then
			run;
		else
			echo "$jarname pid can not killed, start failed"
		fi
	fi
}

function run() {
	backFile;
	echo "$jarname is start..."
	nohup java -Xms2048m -Xmx2048m -jar $jarname >/dev/null 2>&1 &
	sleep 1
	findPid;
	echo "$jarname start finish, pid is $pid"
	isSuccess;
}

function status(){
	if [ ! -n "$pid" ]; then
		echo "$jarname pid is not exist"
	else
		echo "$jarname already started, pid is $pid"
	fi
}

function stop() {
	if [ ! -n "$pid" ]; then
		echo "$jarname pid is not exist"
	else
		echo "$jarname already started, kill pid is $pid"
		kill -9 $pid
		findPid;
		
		if [ ! -n "$pid" ]; then
			echo "$jarname killed success."
		else
			echo "$jarname killed failed."
		fi
	fi
}

findPid;
if [ ! -n "$jarname" ]; then
	echo "jar package name must be specified";
else
	case $2 in
		start) 
			start
		;;
		stop)
			stop
		;;
		status)
			status
		;;
		*)
			echo "support:start|restart|stop|status|null, default is restart"
			restart
		;;
	esac
fi;
exit 0