一、环境准备

(1)CentOS 7
(2)关闭防火墙、关闭selinux

二、软件安装

使用jenkins前需要安装jdk和maven,安装过程相信大家都了解,就不在这里赘述了。
jenkins安装
(1)下载jenkins软件
jenkins下载地址:链接: https://pan.baidu.com/s/1MjPIgNbidtOeJRMMsi2ITw 提取码: twea
jenkins插件下载地址:链接: https://pan.baidu.com/s/1x2PAU9fa2u0OORMbi7k1ew 提取码: bqc2
(2)安装
执行命令:rpm -ivh jenkins-2.215-1.1.noarch.rpm

[root@localhost software]# rpm -ivh jenkins-2.215-1.1.noarch.rpm

jenkins Ant 编译 jenkins ant打包_ant


(3)启动jenkins

执行systemctl start jenkins

如果出现这个问题,是因为自己换件变量配置的jdk位置与jenkins配置文件里指定的位置不一样,可以修改jenkins的配置文件,或者建立软连接。

jenkins Ant 编译 jenkins ant打包_jenkins_02


我这里是使用建立软连接的方式,执行

[root@localhost software]# ln -s /usr/local/java/jdk1.8.0_161/bin/java /usr/bin/java

然后再启动jenkins,则启动成功。

jenkins Ant 编译 jenkins ant打包_ant_03


查看jenkins进程启动成功。

ant安装

1、从http://ant.apache.org 上下载tar.gz版ant

2、复制到/usr下

3、tar -vxzf apahce-ant-1.9.2-bin.tar.gz 解压

4、chown -R yjdabc apahce-ant-1.9.2 改变权限

chown -R :users apahce-ant-1.9.2

chmod -R +x apahce-ant-1.9.2

5、vi /etc/profile 修改系统配置文件

#set Ant enviroment

export ANT_HOME=/usr/apache-ant-1.9.2

export PATH=jenkins Ant 编译 jenkins ant打包_java_04ANT_HOME/bin

6、source /etc/proifle 立刻将配置生效

7、ant -version 测试ant是否生效

三、jenkins配置

(1)默认端口是8080,浏览器访问即可进行配置。

jenkins Ant 编译 jenkins ant打包_ant_05


(2)根据界面的提示信息去服务端查看密码并输入

[root@localhost bin]# cat /var/lib/jenkins/secrets/initialAdminPassword
0d8891c9d27d433787c0bc79eed82173

(3)将0d8891c9d27d433787c0bc79eed82173输入后,点击继续

jenkins Ant 编译 jenkins ant打包_jenkins_06


(4)上个步骤执行成功后,会弹出下面的对话框,提示是否要安装插件。由于安装插件时间很长,或者会因为网络问题导致无法安装,所有我们可以自己在服务器上安装插件,这里点击关闭即可。

jenkins Ant 编译 jenkins ant打包_java_07


(5)开始使用Jenkins

jenkins Ant 编译 jenkins ant打包_jenkins_08

四、jenkins汉化

(1)进入系统管理->插件管理

jenkins Ant 编译 jenkins ant打包_java_09


(2)搜索locale插件,点击立即安装。

jenkins Ant 编译 jenkins ant打包_javaweb_10


(3)进入系统配置,在Locale下添加zh_CN

jenkins Ant 编译 jenkins ant打包_java_11


(4)在插件管理里搜索chinese,并安装Localization: Chinese (Simplified)插件。

jenkins Ant 编译 jenkins ant打包_jenkins_12


(5)勾选安装完成后立即重启按钮。

jenkins Ant 编译 jenkins ant打包_javaweb_13


(6)重新启动后,重新登录页面,即可看到系统已经汉化成功。

jenkins Ant 编译 jenkins ant打包_javaweb_14

五、修改密码

(1)点击当前用户

jenkins Ant 编译 jenkins ant打包_ant_15

(2)点击设置

jenkins Ant 编译 jenkins ant打包_jenkins_16


(3)修改密码

jenkins Ant 编译 jenkins ant打包_java_17

(5)注销重新登录
注销后使用新密码登录。

六、安装jenkins插件

(1)在线安装
在插件管理中的可选插件tab页下,可搜索想要安装的插件进行安装。但可能会因为网络原因或者插件之间的依赖性导致安装失败,需要多次尝试。
(2)服务器上直接安装

[root@jenkins download]# ll
总用量 160580
-rw-r--r-- 1 root root 164431230 3月  27 11:12 jenkins-plugins.tar.gz
[root@jenkins download]#
[root@jenkins download]# ll /var/lib/jenkins/plugins/          #查看Jenkins插件包的目录
总用量 0
[root@jenkins download]# tar xf jenkins-plugins.tar.gz         #解压Jenkins插件包
[root@jenkins download]# 
[root@jenkins download]# ll
总用量 160592
-rw-r--r--  1 root    root    164431230 3月  27 11:12 jenkins-plugins.tar.gz
drwxr-xr-x 97 jenkins jenkins      8192 12月  8 2017 plugins
[root@jenkins download]# 
[root@jenkins download]# ll plugins/ |wc -l                    #插件包共有191个
191
[root@jenkins download]# 
[root@jenkins download]# cp -a plugins/* /var/lib/jenkins/plugins/        #解压后的文件拷贝到Jenkins存放插件包的目录
[root@jenkins download]# 
[root@jenkins download]# ll /var/lib/jenkins/plugins/ |wc -l
191
[root@jenkins download]# 
[root@jenkins download]# /etc/init.d/jenkins restart            #重启Jenkins服务
Restarting jenkins (via systemctl):                        [  确定  ]
[root@jenkins download]#

(3)再次查看界面

jenkins Ant 编译 jenkins ant打包_ant_18

七、jenkins配置

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

jenkins Ant 编译 jenkins ant打包_javaweb_19


1.配置jdk

jenkins Ant 编译 jenkins ant打包_javaweb_20

2.配置maven

jenkins Ant 编译 jenkins ant打包_jenkins Ant 编译_21


3.配置ant

jenkins Ant 编译 jenkins ant打包_ant_22

4.配置ssh

进入系统管理->系统配置

jenkins Ant 编译 jenkins ant打包_java_23


点击高级按钮,配置如下

jenkins Ant 编译 jenkins ant打包_javaweb_24


测试连接成功后,点击保存。

如果用到git、NodeJS、docker配置方法类似。至此jenkins部署全部完成。

八、任务配置

(1)新建任务

jenkins Ant 编译 jenkins ant打包_jenkins_25


(2)配置

源码管理

这里采用svn的版本管理

jenkins Ant 编译 jenkins ant打包_java_26

配置构建工具

jenkins Ant 编译 jenkins ant打包_jenkins_27


jenkins Ant 编译 jenkins ant打包_javaweb_28


由于当前这个项目没用到maven、gradle等构建工具,所以采用ant进行构建。下面是ant的build.xml配置文件。

<?xml version="1.0" encoding="UTF-8"?>  
<project name="ctms" default="makeWar" basedir="/antTest">  
    <property environment="env" />  
    <property name="webapp.name" value="XXX" />  <!-- 项目的名称 -->
    <property name="dist.dir" value="${basedir}/dist" />  <!-- 项目打包到的路径 -->
    <property name="webRoot.dir" value="/var/lib/jenkins/workspace/CTMS/ctms/web"/>  <!-- web项目根文件夹的路径 -->
    <property name="src.dir" value="/var/lib/jenkins/workspace/CTMS/ctms/java_src" />   <!-- src文件夹路径 -->
    <property name="base" value="/var/lib/jenkins/workspace/CTMS/base/java_src"/>      <!-- base项目src文件夹路径 -->
    <property name="lib.dir" value="/var/lib/jenkins/workspace/CTMS/ctms/web/WEB-INF/lib" />  <!-- 依赖的jar包所在路径 -->
    <property name="build.dir" value="${basedir}/build" />                                <!-- 打包到的路径 -->
    <property name="build.dir.base" value="${basedir}/build/base" />					<!-- base项目打包的路径 -->
    <property name="jre.dir" value="/usr/local/java/jdk1.8.0_161/jre" />               <!-- jre的路径 -->
    <property name="properties.dir" value="/var/lib/jenkins/workspace/CTMS/properties" /> <!-- 配置文件的路径 -->
    <property name="sqlfolder" value="/var/lib/jenkins/workspace/CTMS/postgre" />         <!-- 执行的脚本文件存放的路径 -->
    <property name="sqlbakdir" value="/var/lib/jenkins/workspace/CTMS/result/success" />   <!-- 执行成功的脚本文件存放的路径 -->
    <property name="Sqllogfile" value="/var/lib/jenkins/workspace/CTMS/result/log.txt" />   <!-- sql执行日志的路径 -->
    <property name="db.driver" value="org.postgresql.Driver" />                             <!-- 数据库连接驱动 -->
    <property name="db.host" value="xxx" /> 										<!-- 数据库地址 -->
    <property name="db.port" value="xxx" /> 												<!-- 数据库端口 -->
    <property name="db.name" value="xxx" /> 											<!-- 数据库名 -->
    <property name="db.user" value="xxx" /> 											<!-- 数据库用户名 -->			
    <property name="db.pwd" value="xxx" /> 											<!-- 数据库  -->
    <property name="errMsg" value="执行脚本出错了" /> 										
    <property name="svnSqlPath" value="/var/lib/jenkins/workspace/CTMS/svnSqlFile" />       <!-- 从svn更新的脚本文件存放的路径 -->
	<!--读取配置文件,找到要执行的所有sql-->
    <property file="/var/lib/jenkins/workspace/CTMS/sql.properties"/>                       <!-- 配置了要执行的sql文件名称 -->
	
    <!-- 初始化classpath -->  
    <path id="project.classpath">  
        <fileset dir="${lib.dir}">  
            <include name="**/*.jar" />  
        </fileset>  
        <!-- 添加jre类路径 -->  
        <fileset dir="${jre.dir}/lib">  
            <include name="*.jar" />  
        </fileset>      
    </path>  

    <pathconvert pathsep="${line.separator}|   |-- "  
             property="echo.path.compile"  
             refid="project.classpath">  
    </pathconvert>  

    <target name="print_classpath">  
        <echo message="|-- compile classpath"/>  
        <echo message="|   |"/>  
        <echo message="|   |-- ${echo.path.compile}"/>  
    </target>  
	<!--=====================================================================================================================================-->
	<!--将准备升级执行的sql复制到指定目录下 以备执行-->	
	<target name="copySql" depends="compileCtms">
	    <for list="${sqlName}" delimiter="," param = "sqlFile">
	        <sequential>
	            <echo message = "file = @{sqlFile}"/>
	        	<copy todir="${sqlfolder}/sql">  
	        		  <fileset dir="${svnSqlPath}">  
	        		        <include name="@{sqlFile}" />  
	        		  </fileset>   
	            </copy>
	        </sequential>
	    </for>
	</target>
	<!--=====================================================================================================================================-->
	<!--执行sql脚本-->	
	<taskdef resource="net/sf/antcontrib/antlib.xml" classpath="${lib.dir}/ant-contrib-1.0b3.jar"/>
	<target name="runSqlInFolder" depends="copySql">
	    <echo>Run the SQL at Folder: ${sqlfolder}</echo>
	    <echo>DB Host: ${db.host}</echo>
	    <echo>DB Host: ${db.port}</echo>
	    <echo>DB Name: ${db.name}</echo>
	    <echo>DB User: ${db.user}</echo>
	    <trycatch property="errMsg">
	        <try>            
	        	<echo>try start</echo>
	            <for param="folder">
	               <path>
	                   <sort xmlns:rcmp="antlib:org.apache.tools.ant.types.resources.comparators">
	                       <dirset dir="${sqlfolder}" includes="*" />                        
	                   </sort>
	               </path>
	               <sequential>
	                    <echo>SQL Folder: @{folder}</echo>    
	                    <for param="file">
	                        <path>
	                            <sort xmlns:rcmp="antlib:org.apache.tools.ant.types.resources.comparators">
	                                <fileset dir="@{folder}" includes="*.sql" casesensitive="false"/>                                            
	                            </sort>
	                        </path>
	                        <sequential>
	                        <echo>SQL: @{file}</echo>                             
	                        <execsql
	                            dbhost="${db.host}"    
	                            dbport="${db.port}"    
	                            dbname="${db.name}" 
	                            dbuser="${db.user}" 
	                            dbpwd="${db.pwd}"
	                            sqlfile="@{file}"
	                            logfile="${Sqllogfile}"/>
	                        	
	                        </sequential>
	              
	                    </for>
	                </sequential>    
	            </for>
	            <echo>Finished running all SQL</echo>
	     </try>
	     <catch>
	            <echo>Error found when running SQL</echo>
	            <echo>Log file can be found in:</echo>
	            <move file="${Sqllogfile}" todir="${sqlbakdir}/err"/>
	            <fail>Error Occur</fail>
	     </catch>
	            <finally>
	            </finally>
	        </trycatch>
	    </target>

	<macrodef name="execsql" description="Run single SQL file.">
	    <attribute name="dbhost" description="Host Name/ IP of the DB"/>
	    <attribute name="dbport" description="DB Port"/>
	    <attribute name="dbname" description="DB name"/>
	    <attribute name="dbuser" description="DB User name"/>
	    <attribute name="dbpwd" description="DB Password"/>
	    <attribute name="sqlfile" description="SQL file to be run"/>
	    <attribute name="logfile" default="sql.log" description="Log file"/>
	        <sequential>
	            <echo>Log file @{logfile}</echo>                    
	            <record name="@{logfile}" action="start"/>    
	            <echo>Log file @{logfile}</echo>                    
	            <if>
	                <contains string="@{sqlfile}" substring="PROCEDURE"/>
	                <then>
	                   <sql driver="${db.driver}"
	                	    url="jdbc:postgresql://@{dbhost}:@{dbport}/@{dbname}"
	                	    userid="@{dbuser}"
	                	    password="@{dbpwd}"
	                	    encoding="UTF-8"
	                	    autocommit="true"
	                	    print="true"
							delimiter="/"
							delimitertype="row">
	                        <transaction src="@{sqlfile}"/>
	                    </sql>
	                </then>
	                <else>
	                	   <echo>if 2</echo>
	                	   <echo>driver: ${db.driver}</echo>
	                	   <echo>url:jdbc:postgresql://@{dbhost}:@{dbport}/@{dbname}</echo>
	                	   <echo>usr:@{dbuser}</echo>
	                	   <echo>mima:@{dbpwd}</echo>
	                	   <echo>file:@{sqlfile}</echo>
	                	<sql driver="${db.driver}"
	                	    url="jdbc:postgresql://@{dbhost}:@{dbport}/@{dbname}"
	                	    userid="@{dbuser}"
	                	    password="@{dbpwd}"
	                	    encoding="UTF-8"
	                	    autocommit="true"
	                	    print="true"
	                		>
	                		 <classpath refid="project.classpath"/>
	                        <transaction src="@{sqlfile}"/>
	                    </sql>
	                </else>
	            </if>
	            <record name="@{logfile}" action="stop"/> 
	        </sequential>
	    </macrodef>
	<!-- 测试连接数据库 -->
	<!--===================================================================================================================================-->
	<target name="testDoSql">
		<sequential>
		<record name="D:/antTest/sqlfolder/sql/sql.txt" action="start"/> 
	        <echo message="Initializing database... If error occurs,let it be." />
	        <sql
	        	driver="org.postgresql.Driver"
	            url="jdbc:postgresql://192.168.131.53:5432/ctms_efile"
	            userid="ctms_efile"
	            password="ctms_efile"
	            src="D:/antTest/sqlfolder/sql/antTest.sql"
	        	encoding="UTF-8"
	           >
	          <classpath refid="project.classpath"/>
	        </sql>
		
			<record name="D:/antTest/sqlfolder/sql/sql.txt" action="stop"/> 
		</sequential>
	    </target> 
	<!--===================================================================================================================================-->
	
	
    <!-- 删除之前的目录结构 -->  
    <target name="clear" description="清理旧文件">  
        <delete dir="${build.dir}" />  
        <delete dir="${build.dir.base}" />
        <delete dir="${dist.dir}" />       
    </target>  

    <!-- 创建目录结构 -->  
    <target name="init" depends="clear" description="创建初始化目录结构">  
        <mkdir dir="${build.dir}/classes" /> 
        <mkdir dir="${build.dir.base}/classes" />      
        <mkdir dir="${dist.dir}" />  
    </target> 


    <!-- 编译java -->  
    <target name="compileBase" depends="init" description="编译java文件">  
        <echo message="compileBase" />  
        <javac srcdir="${base}" destdir="${build.dir.base}/classes"   
            includeantruntime="false" nowarn="on"   
            source="1.8" target="1.8" deprecation="true" debug="true"   
            encoding="UTF-8" classpathref="project.classpath"   
            >  
            <compilerarg line="-Xlint:unchecked" />  
        </javac>  
        <echo message="end compileBusiManager..." />  
    </target>

	 <copy todir="${build.dir}/classes">  
	            <fileset dir="${src.dir}">  
	                <include name="**/*.ftl" />  
	            </fileset>   
	            <fileset dir="${src.dir}">  
	                <include name="**/*.wsdl" />  
	            </fileset>   
	        </copy>
    <!-- 将class文件打成 jar包 -->  
    <!-- base打jar包   --> 
    <target name="compileBaseJar" depends="compileBase">
    	<delete file="${base}/jdbc.properties" />
    	<copy todir="${base}">
    		<fileset dir="${properties.dir}">  
    			<include name="jdbc.properties" />  
    		</fileset>   
    	</copy>
        <jar jarfile="${lib.dir}/base.jar"> 
            <fileset dir="${build.dir.base}/classes">   
                <include name="**/*.class"/>   
            </fileset> 
            <fileset dir="${base}">   
                <include name="**/*.xml" />  
                <include name="**/*.properties" />  
                <include name="**/*.sql" />   
            </fileset>   
        </jar>   
    </target>

     <!-- 编译java -->  
    <target name="compileCtms" depends="compileBaseJar" description="编译java文件">  
        <echo message="begin compile..." />  
        <javac srcdir="${src.dir}" destdir="${build.dir}/classes"   
            includeantruntime="false" nowarn="on"   
            source="1.8" target="1.8" deprecation="true" debug="true"   
            encoding="UTF-8" classpathref="project.classpath"   
            >  
            <compilerarg line="-Xlint:unchecked" />
			<compilerarg value="-XDignore.symbol.file" />			
        </javac>  
        <copy todir="${build.dir}/classes">  
            <fileset dir="${src.dir}">  
                <include name="**/*.ftl" />  
            </fileset>   
            <fileset dir="${src.dir}">  
                <include name="**/*.wsdl" />  
            </fileset>   
        </copy>  
    	<!--删除META-INF文件夹-->
    	<delete dir="${build.dir}/classes/META-INF" />  
        <echo message="end compile..." />  
    </target>

    <!-- 打成war包, 名称默认为 项目名 -->  
    <target name="makeWar" depends="runSqlInFolder" description="将工程打成war包">  
        <echo message="begin war..." />  
        <war destfile="${dist.dir}/${webapp.name}.war" basedir="${webRoot.dir}"   
            webxml="${webRoot.dir}/WEB-INF/web.xml">  
            <classes dir="${build.dir}/classes" />  
        </war>  
        <echo message="end war..." />  
    </target>  
</project>

上面配置文件主要执行的可以说是3件事情,分别是执行sql脚本、编译项目、打包项目,下面分别介绍一下各个步骤。

(1)执行sql

这里的实现方法所有sql脚本文件先提交svn,然后在sql.properties配置文件中配置了这次发布需要执行的sql文件。然后读取到配置文件后,会将需要更新的sql脚本文件复制到指定目录。最后会将这个指定目录下的sql文件全部遍历然后在数据库执行。

(2)编译项目

当前项目是有一个web项目XXX,然后依赖一个父项目base,所以整体编译过程为先编译base,然后把base打成jar包,放到主项目的web/WEB-INF/lib目录下,作为主项目的依赖。

(3)打包项目

编译web项目XXX,然后将其打成war包。

具体实现逻辑参考上面的build.xml文件。

配置构建后操作

构建成功后的步骤就是将war包发送到tomcat下,并启动tomcat。

jenkins Ant 编译 jenkins ant打包_java_29

jenkins Ant 编译 jenkins ant打包_java_30


(图片中那个是jenkins工作空间,而不是工作工具。。。打错字了。。)

将war包发送到远程服务器之后,要执行的脚本就是停掉tomcat服务器,然后再重新启动。

echo "*******start to restart tomcat********"

cd /usr/local/tomcat/apache-tomcat-jenkinsTest/apache-tomcat-9.0.34/bin
 
#stop tomcat
echo "*******shutdown the tomcat********"
sh shutdown.sh
 
sleep 10
 
echo "*******start tomcat********"
sh startup.sh

九、进行构建

jenkins Ant 编译 jenkins ant打包_java_31

十、参考文章