github+spring boot+jenkins实现自动化部署,并且通过域名访问
github+spring boot+jenkins实现自动化部署,并且通过域名访问
目的:
之前写过jenkins实现自动化集成的例子,也试过通过域名直接访问项目,那么在想为啥不能合二为一呢,因为现在项目都是通过域名直接访问的,所以上手就干,之前的思路很简单直接将部署好的war包通过jenkins的构建后步骤这一选项发送到远程tomcat下,但是后来发现不行,因为通过域名访问项目我是采用的配置tomcat的server.xml文件方式,但是现在tomcat已经启动在配置修改很难,而且烦。
所以有两种方式解决:
还是老方法,但是不修改server.xml内容,将war发送到tomcat的webapps文件下之后,通过配置负载均衡,让访问域名直接跳转到项目页面(但是无奈本菜鸟还没学)
第二种就是今天要讲的,比较low的方法,但也简单。一开始是一样的jenkins自动化部署构建项目,此时war包在jenkins的workspace文件夹下,那么通过构建后命令将war包发送到指定要运行的tomcat的webapps文件夹下(当然现在的tomcat的server.xml文件是修改过的,一会讲),然后启动tomcat不就行了么
准备工作:
spring boot项目打包成war注意事项不用多说网上例子很多无非就是注意启动类和pom中tomcat配置,
jenkins如何自动化部署网上一搜一大把,
还有如果将域名和ip绑定看这个
主要的server.xml文件如下
<?xml version='1.0' encoding='utf-8'?>
<Server port="8015" shutdown="SHUTDOWN">
<Listener className="org.apache.catalina.startup.VersionLoggerListener" />
<Listener className="org.apache.catalina.core.AprLifecycleListener" SSLEngine="on" />
<Listener className="org.apache.catalina.core.JreMemoryLeakPreventionListener" />
<Listener className="org.apache.catalina.mbeans.GlobalResourcesLifecycleListener" />
<Listener className="org.apache.catalina.core.ThreadLocalLeakPreventionListener" />
<GlobalNamingResources>
<Resource name="UserDatabase" auth="Container"
type="org.apache.catalina.UserDatabase"
description="User database that can be updated and saved"
factory="org.apache.catalina.users.MemoryUserDatabaseFactory"
pathname="conf/tomcat-users.xml" />
</GlobalNamingResources>
<Service name="Catalina">
<!-- 这里的8080改成80商用端口-->
<Connector port="80" protocol="HTTP/1.1"
connectionTimeout="20000"
redirectPort="8443" />
<Connector port="8019" protocol="AJP/1.3" redirectPort="8443" />
//这里原来是localhost改成自己的域名
<Engine name="Catalina" defaultHost="www.****.xyz" >
<Realm className="org.apache.catalina.realm.LockOutRealm">
<Realm className="org.apache.catalina.realm.UserDatabaseRealm"
resourceName="UserDatabase"/>
</Realm>
//这里name中原来是localhost改访问的域名
<Host name="www.***.xyz" appBase="webapps"
unpackWARs="true" autoDeploy="true">
//docBase写全
<Context docBase="/opt/tomcat-8_8081/webapps/springBootDemo" path="" reloadable="true"/>
<Valve className="org.apache.catalina.valves.AccessLogValve" directory="logs"
prefix="localhost_access_log" suffix=".txt"
pattern="%h %l %u %t "%r" %s %b" />
</Host>
</Engine>
</Service>
</Server>
要看下端口号是否已经开放
开始动手
1.首先在jenkins中新建项目,还是选择*构建
2.配置git
3.配置maven
4.重点来了
在构建步骤中选择执行shell(英文可能有出入但是翻译过来差不多)
这是我花费最长时间的地方,本人linux也是刚学,这个命令都是简单的shell命令,也没有经过严格测试,但是至少满足现在的需求
#最后运行的tomcat的目录
TOMCAT_HOME="/opt/tomcat-8_8081"
#tomcat运行端口
TOMCAT_PORT=8081
#jenkins打包成war包之后存放的目录
JENKINS_TARGET_HOME="/root/.jenkins/workspace/SpringBootDemo_free/target"
#jenkins打包成war包的名字(这个war的名字和pom文件配置有关)
JENKINS_WAR_NAME="SpringBoot-1.0-SNAPSHOT.war"
#jenkins打包成war包的路径
JENKINS_WAR_HOME=$JENKINS_TARGET_HOME/$JENKINS_WAR_NAME
#tomcat下war最终运行的名字(可以不要,只是本人看着难受)
FINAL_WAR_NAME="springBootDemo.war"
echo "[step 1:] kill tomcat process is start"
#获取指定运行的tomcat进程号
tomcat_pid=`ps -ef | grep $TOMCAT_HOME | grep -v grep | awk '{print $2}'`
#如果又进程就杀死
#这里的[ -n "$tomcat_pid" ]不能错,引号去掉判断不准,注意空格,这都是我踩过的坑啊
if [ -n "$tomcat_pid" ]
then
echo $tomcat_pid "tomcat process is starting========"
kill -9 $tomcat_pid
sleep 3
else
echo "tomcat is shutdown........."
fi
#获取指定运行的tomcat进程号
#tomcat_pid=`ps -ef | grep $TOMECAT_HOME | grep -v grep | awk '{print $2}'`
#如果存在指定运行的tomcat进程,直接循环kill,直到没有
#while [ -n "$tomcat_pid" ]
#do
# #statements
# kill -9 $tomcat_pid
# sleep 3
# tomcat_pid=`ps -ef | grep $TOMECAT_HOME | grep -v grep | awk '{print $2}'`
# echo "scan tomcat pid == " $tomcat_pid
#done
sleep 3
#输出语句而已
echo "[setp 2: ] cp " $JENKINS_WAR_HOME "to" $TOMCAT_HOME"/webapps/"
#将war包移动到tomcat的webapp目录下
yes|cp $JENKINS_WAR_HOME $TOMCAT_HOME/webapps/
cd $TOMCAT_HOME/webapps/
echo "[setp 3 ] 准备运行环境....."
#将以前存在的war包删除(如果没有不会报错)
rm -rf $FINAL_WAR_NAME
#将war包重命名
mv $JENKINS_WAR_NAME $FINAL_WAR_NAME
#将tomcat启动 的log日志清空(可以不要)
echo "" > $TOMCAT_HOME/logs/catalina.out
echo "[setp 4::] start tomcat "
#在jinkins环境中一定要加这句话,否则这个脚本进程最后会被杀死,tomcat不起动,jenkins也不报错
export BUILD_ID=dontKillMe
#运行tomcat
sh $TOMCAT_HOME/bin/startup.sh &
cat $TOMCAT_HOME/logs/catalina.out
检查
:
ps -ef|grep tomcat
如果有一长串,
root 11310 1 4 21:24 ? 00:02:11 /opt/jdk1.8/bin/java -Djava.util.logging.config.file=/opt/tomcat-8_8081/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dignore.endorsed.dirs= -classpath /opt/tomcat-8_8081/bin/bootstrap.jar:/opt/tomcat-8_8081/bin/tomcat-juli.jar -Dcatalina.base=/opt/tomcat-8_8081 -Dcatalina.home=/opt/tomcat-8_8081 -Djava.io.tmpdir=/opt/tomcat-8_8081/temp org.apache.catalina.startup.Bootstrap start
说明tomcat启动成功,
查看日志有没有报错
cat /opt/tomcat-8_8080/logs/catalina.out
没有的话输入域名即可,如果页面加载慢不要慌等着,要充钱,服务器配置不行就是这样,只要没有显示什么拒绝访问啥的都行
大功告成!!!
注意:
虚拟机环境中运行的指定tomcat的进程最好不要有多个,上面的if…fi命令只适合单个指定tomcat进程,如果有多个,可以直接kill -9 进程号 ,也可以试**释的while do…done语句,虽然不会报错,但是有点小毛病,如果解决的朋友希望在下面留言。
最后总结:
现在我写的这行demo是jenkins和tomcat在同一个服务器中。如果想两个在不同的虚拟机环境,还是有其他方案,比如说
1.将jenkins部署好的war包利用jenkins的远程ssh连接推送发送到指定的文件夹下,然后再启动tomcat
2.或者说再low一点,在远程虚拟机上建立两个tomcat,一个是真正运行web项目的,一个是和jenkins进行远程连接的,将jenkins部署好的war包通过构建后发送到指定远程的和jenkins连接的tomcat中,然后再将war包移动到要运行的tomcat下,在启动tomcat
3.高大上一些,就是加上Nginx,前面的部署不变,tomcat的server.xml文件也不变(就是tomcat初始的server.xml),然后访问域名的时候,让Nginx重定向到服务器ip地址上,(后续研究学习再更新博客)