建设一网站有什么用,企业手机网站建设提升用户体验的三个点,只做外贸的公司网站,知名网络公司有哪些Jenkins教程(自动化部署)
1. Jenkins是什么#xff1f;
Jenkins是一个开源的、提供友好操作界面的持续集成(CI)工具#xff0c;广泛用于项目开发#xff0c;具有自动化构建、测试和部署等功能。Jenkins用Java语言编写#xff0c;可在Tomcat等流行的servlet容器中运行
Jenkins是一个开源的、提供友好操作界面的持续集成(CI)工具广泛用于项目开发具有自动化构建、测试和部署等功能。Jenkins用Java语言编写可在Tomcat等流行的servlet容器中运行也可独立运行。通常与版本管理工具(SCM)、构建工具结合使用。
2. 什么是持续集成CICD
因为开发部门同时维护多个版本多个版本的发布测试需要大量人力所以要有一个专业的持续集成工具来管理持续重复的工作。
个人理解说白了就是把代码测试、打包、发布等工作交给一些工具来自动完成。这样可以提高效率减少失误开发人员只需要关心开发和提交代码到Git就可以了。
3. Jenkins的安装
夸克网盘分享夸克网盘是夸克推出的一款云服务产品功能包括云存储、高清看剧、文件在线解压、PDF一键转换等。通过夸克网盘可随时随地管理和使用照片、文档、手机资料目前支持Android、iOS、PC、iPad。https://pan.quark.cn/s/631fd86feeda 夸克网盘分享https://pan.quark.cn/s/631fd86feeda 链接里包含jenkins.war maven jdk17 jenkins-start.sh简易shell命令 maven正常解压配置环境变量 记得修改maven目录里config的settings.xml配置 jdk如果系统jdk就为17 可以不用下载不是的话就将jdk压缩包解压将Jenkins-start.sh里面的java路径换成所解压的文件夹就行 1准备条件
安装JDK
下载JDK压缩包,并上传至Linux某个目录下解压。
①. 配置jdk的环境变量
#进入/etc/profile配置文件
vim /etc/profile
②. 将以下代码填入到profile文件内底
export JAVA_HOME/usr/wubin/jdk11
export CLASSPATH.:$JAVA_HOME/lib/dt.jar:$JAVA_HOME/lib/tools.jar
export PATH$JAVA_HOME/bin:$PATH
③. 使配置生效
source /etc/profile
④. 检测java环境信息
javac
输入javac后出现以下信息则安装jdk成功 ps:jenkins不同版本对jdk版本有不同要求如果系统里面是jdk8但是想在不升级jdk版本情况下使用更高版本的jenkins(比如要求jdk17),也可直接在jenkins启动时指定jdk路径就不用修改系统里配置的jdk版本
2安装Jenkins
1. 下载jenkins
wget http://mirrors.jenkins.io/war-stable/latest/jenkins.war
2. 启动jenkins
# 使用nohup命令启动 nohup 当虚拟机黑屏时 也会运行 日志—输出到jenkins.log 后台运行
nohup java -jar /usr/wubin/jenkins.war --httpPort8777 --httpsPort8778 /usr/wubin/jenkins.log 21
3. 使用tail命令查看启动日志日志中会输出jenkins密码 4. 通过浏览器访问jenkins(端口号必须为8777)
http://你的ip:8777 点击安装推荐的插件 (3)Jenkins中配置JDK路径
jenkins-》全局工具配置-》JDK-》新增JDK (4)Jenkins忘记密码的解决方案 4. 集成Git
为了Jenkins能够拉取代码需要安装Git环境和jenkins对应的Git插件
(1) CentOS 7 上安装Git环境
# 安装
$ yum install git -y
# 查看版本
$ git --version
复制
(2) Jenkins安装Git插件 (3) Jenkins配置Git环境
此处无需在jenkins中配置Git环境采用默认生成的即可 (4) Gitee上任意建一个仓库 (5) 测试凭据是否能够使用
jenkins-》新建任务-》自由风格项目 进入jenkins的工作空间查看文件是否拉取下来所有拉取的文件都会存放在jenkins工作空间中 到这一步用户名和密码方式的凭证已经打通Git
5. 凭证配置
凭据就是用来存储需要密文保护的数据库密码、Gitee密码信息、Docker私有仓库密码等以便 Jenkins可以和这些第三方的应用进行交互。
1. 凭证插件安装Credentials Binding 该插件默认在一开始就会被安装安装后在jenkins-》系统管理-》安全栏目会出现Manage Credentials选项若没有需要安装插件并重启。 6. Maven集成
在jenkins上发布Java项目时需要使用Maven来进行构建打包Gradle项目则需要安装配置Gradle
回到顶部
(1) 下载安装
# 找一个目录存放maven
cd /usr/wubin/# 从阿里云上下载maven安装包
wget https://mirrors.aliyun.com/apache/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz# 解压
tar -zxvf apache-maven-3.6.3-bin.tar.gz# 当前maven的安装目录为
/usr/wubin/
apache-maven-3.6.3回到顶部
(2) 环境配置
vi /etc/profile在最后面JDK配置上作出一些更改
export MAVEN_HOME
/usr/wubin/
apache-maven-3.6.3export PATH$JAVA_HOME/bin:$MAVEN_HOME/bin:$PATH
复制
回到顶部
(3) 使配置生效并查看安装情况
source /etc/profile
mvn -version
回到顶部
(4) Jenkins配置Maven (5) 安装Maven插件 (6) 在/data/software目录下新建一个repository文件夹用来作为maven的仓库
$ cd /usr/wubin
$ mkdir repository
复制 (7) 使用root账户修改Maven的settings.xml文件指定仓库目录和阿里云镜像
settings xmlnshttp://maven.apache.org/SETTINGS/1.0.0xmlns:xsihttp://www.w3.org/2001/XMLSchema-instancexsi:schemaLocationhttp://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd!--本地仓库-- localRepository/data/software/repository/localRepositorymirrors!--阿里云镜像--mirroridaliyun-maven/idmirrorOfcentral/mirrorOfnamealiyun maven mirror/nameurlhttp://maven.aliyun.com/nexus/content/groups/public//url/mirror/mirrors......
/settings
(8) Maven测试项目构建
接下来的步骤是将java项目传到Gitee上供jenkins拉取打包如果运维同学不懂Java代码可以直接将我的Git项目fork或采用gitlab 等其他方式进行拉取。
新建Maven项目 在码云上建一个同名的git项目 使用Git上传到码云
使用git bash命令将项目初始化无论是传到Gitee、GitHub、GitLab、Codeup步骤一样如果对Git的安装部署不熟悉
# 进入到本地的项目文件夹
$ cd existing_folder
# 初始化仓库
$ git init# 添加文件至工作区并提交
$ git add .
$ git commit -m first commit# 关联Gitee远程仓库
$ git remote add origin https://gitee.com/nobug8/it235-jenkins-jar.git# 将本地仓库推送到远程仓库的master分支此处会弹出用户名密码交互
$ git push -u origin master## 如果push报错可以先拉取一下会有新的gitee生成的文件拉下来然后重新添加提交并push
$ git pull origin master --allow-unrelated-histories
$ git add .
$ git commit -m 拉取下来合并后再次提交
$ git push -u origin master
复制 (9) Jenkins添加Maven项目任务
①. 新建任务 ②. 编写Maven编译命令 ③. 构建并查看控制台日志
保存后点击立即构建然后进入日志控制台查看日志 从日志可以看到代码已经在拉取了而且走的事阿里云仓库第一次拉取过程会比较长。
通过查看/data/software/repository可以看到有存放拉取的jar包通过这2个证据可以证明settings.xml文件配置成功且有效
ps:如果使用git账号密码拉取代码即使权限都已经给够了还是出现403等等一些问题可以考虑使用ApiToken方式拉去代码在git/gitlab创建apiToken在凭证管理地方加上凭证 构建成功后查看jenkins的workspace目录下的jar包 到此Maven集成完毕
配置Post Steps选中执行shell 7. 配置SSH免密登录
由于jenkins构建消耗内存极大一般jenkins是一台单独的工具机器Java项目一般在其他的机器上这里我重新安装一台虚拟机
应用服务器信息
IP192.168.223.129JDK1.8userroot部署路径/data/app/my-boot端口9010
免密登录主要是方便jenkins服务器192.168.223.128的root用户—》应用服务器192.168.223.129的root用户上的jar包拷贝部署本就是jar包拷贝的过程
在192.168.223.128机器上使用root用户生成秘钥注意此处是root用户
$ ssh-keygen -t rsa
# 3次回车
复制
运行后会在当前用户的根目录生成一个.ssh文件夹 ssh文件夹中的文件描述
id_rsa : 生成的私钥文件id_rsa.pub 生成的公钥文件
接下来需要将公钥导入到认证文件中
$ cat ~/.ssh/id_rsa.pub ~/.ssh/authorized_keys
复制
如果希望ssh公钥生效需满足至少下面两个条件
.ssh目录的权限必须是700.ssh/authorized_keys文件权限必须是600
给对应文件授权
$ chmod 700 ~/.ssh
$ chmod 600 ~/.ssh/authorized_keys
复制
将authorized_keys文件拷贝到另一台应用服务器的root用户.ssh目录下
# 在应用服务器192.168.223.129上用root用户创建/root/.ssh文件夹 mkdir -p /root/.ssh# 在jenkins服务器192.168.223.128上将pub公钥文件拷贝到应用服务器的.ssh目录下scp -p ~/.ssh/id_rsa.pub root192.168.223.129:/root/.ssh/authorized_keys
复制
在jenkins192.168.223.128服务器上进行免密连接测试
# 在jenkins服务器的/root/目录下创建filetest文件并拷贝到应用服务器
$ cd ~/
$ touch filetest
$ scp -p filetest root192.168.223.129:/root/filetest
# 进入到应用服务器192.168.223.129检查/root目录下是否出现filetest# 在jenkins服务器上使用ssh进行免密连接测试成功后会出现Last Login的提示
$ ssh root192.168.223.129
Last login: Sun Sep 20 21:53:03 2020
$ exit
复制
到此免密登录和拷贝实现成功为接下来jar包部署提供了快捷的帮助
8. 编写Jenkins发布脚本 注意下面代码第6行代码server_ips”需要部署到的机器ip”
#!/bin/bashecho 部署的目录和项目名称
DIR/data/app
projectNamemy-bootecho 待部署的应用服务器可多台
server_ips192.168.223.139
for server_ip in ${server_ips[]}
doecho ssh连接进行备份操作
ssh -Tq -oStrictHostKeyCheckingno root${server_ip} EOF
mkdir -p $DIR/backup/${projectName}
mkdir -p $DIR/${projectName}
if [ -f $DIR/${projectName}/${projectName}.jar ];thenmv $DIR/${projectName}/${projectName}.jar $DIR/backup/${projectName}/${projectName}-date %Y%m%d_%H%M%S.jar
fi
EOFecho 拷贝jar包到目标服务器的tmp目录
scp -q -oStrictHostKeyCheckingno ${WORKSPACE}/target/*.jar root${server_ip}:/tmp/${projectName}.jarecho ssh远程连接进行发布操作
ssh -q -oStrictHostKeyCheckingno root${server_ip} EOF
mv /tmp/${projectName}.jar $DIR/${projectName}/${projectName}.jarEOFdoneecho success
最新脚本以端口kill进程
#!/bin/bash# 配置变量
LOG_FILE/home/xxx/.jenkins/workspace/whale-mgnt-service/startup.log
JAR_PATH/home/xxx/.jenkins/workspace/whale-mgnt-service/whale-mgnt-service/target/whale-mgnt-service.jar
APP_PORT8081
MAX_ATTEMPTS60
INTERVAL5# 清空之前的日志
echo $LOG_FILE# 使用多种方式查找和终止进程
kill_process_by_port() {local port$1echo Checking for processes using port $port...# 方法1: 使用netstat查找local pid$(sudo netstat -tlnp | grep :${port} | awk {print $7} | cut -d/ -f1)# 方法2: 如果方法1失败使用另一种方式if [ -z $pid ]; thenpid$(sudo ss -tlnp | grep :${port} | awk {print $6} | cut -d, -f2 | cut -d -f2)fi# 方法3: 如果还是失败尝试使用 ps 和 grepif [ -z $pid ]; thenpid$(ps aux | grep whale-mgnt-service | grep -v grep | awk {print $2})fiif [ ! -z $pid ]; thenecho Found process(es) with PID: $pidfor single_pid in $pid; doecho Stopping process $single_pidsudo kill -15 $single_pid 2/dev/null || truesleep 3if ps -p $single_pid /dev/null 21; thenecho Force killing process $single_pidsudo kill -9 $single_pid 2/dev/null || truesleep 2fidoneelseecho No process ID found, trying alternative methods...# 尝试直接通过应用名称终止sudo pkill -f whale-service || truefi# 等待端口释放sleep 5# 检查端口是否已释放if sudo netstat -tlnp | grep :${port} /dev/null; thenecho Warning: Port $port is still in usereturn 1fiecho Port $port is now availablereturn 0
}# 确保端口可用
echo Ensuring port $APP_PORT is available...
for i in {1..3}; doecho Attempt $i to free port $APP_PORTkill_process_by_port $APP_PORTif ! sudo netstat -tlnp | grep :${APP_PORT} /dev/null; thenecho Port successfully freedbreakfiecho Current processes using port $APP_PORT:sudo netstat -tlnp | grep :${APP_PORT}sleep 5
done# 最终检查端口
if sudo netstat -tlnp | grep :${APP_PORT} /dev/null; thenecho Failed to free port $APP_PORT after multiple attemptsecho Current processes using port $APP_PORT:sudo netstat -tlnp | grep :${APP_PORT}# 最后的紧急措施echo Attempting emergency measures...sudo fuser -k ${APP_PORT}/tcp 2/dev/null || truesudo pkill -9 -f whale-mgnt-service 2/dev/null || truesleep 5if sudo netstat -tlnp | grep :${APP_PORT} /dev/null; thenecho All attempts to free port failed. Please check manually.exit 1fi
fi# 启动服务
echo Starting service...
sudo nohup java -jar \-Xms256m \-Xmx512m \-XX:MaxMetaspaceSize256m \-XX:HeapDumpOnOutOfMemoryError \-XX:HeapDumpPath/tmp/ \-XX:UseG1GC \-XX:MaxGCPauseMillis200 \$JAR_PATH \--spring.profiles.activetest \--server.port$APP_PORT \--spring.jpa.open-in-viewfalse \--server.tomcat.max-threads50 \--server.tomcat.min-spare-threads20 \--spring.task.execution.pool.core-size5 \--spring.task.execution.pool.max-size10 \--spring.task.execution.pool.queue-capacity100 \ $LOG_FILE 21 PID$!echo Starting service with PID: $PID
echo Waiting for service to start...# 给予初始化时间
sleep 15attempt1
while [ $attempt -le $MAX_ATTEMPTS ]; do# 检查进程是否存在if ! ps -p $PID /dev/null; thenecho Process died unexpectedly. Check logs:tail -n 50 $LOG_FILEexit 1fi# 检查端口和应用状态if netstat -tunlp 2/dev/null | grep :$APP_PORT /dev/null; thenif grep -q Started WhaleManagementApplication $LOG_FILE; thenecho Application started successfullysleep 5if ps -p $PID /dev/null; thenecho Service is running stablyecho Final memory usage:free -mecho Process memory usage:ps -o pid,ppid,%mem,rss,command -p $PIDexit 0elseecho Process died after startuptail -n 50 $LOG_FILEexit 1fififiecho Attempt $attempt of $MAX_ATTEMPTS - Service still starting...# 检查启动日志中的错误if grep -q Port $APP_PORT was already in use $LOG_FILE; thenecho Port conflict detected!echo Current port status:sudo netstat -tunlp | grep :$APP_PORT[ -n $PID ] kill -9 $PID 2/dev/null || trueexit 1fiecho Recent log entries:tail -n 10 $LOG_FILEsleep $INTERVALattempt$((attempt1))
doneecho Service failed to start within timeout. Last 50 lines of log:
tail -n 50 $LOG_FILE
[ -n $PID ] kill -9 $PID 2/dev/null || true
exit 1 9. 编写应用启动脚本
在/data/app/my-boot目录下创建启动脚本start.sh
$ touch start.sh
$ vi start.sh
# 将下面代码粘贴到start.sh中
#!/bin/bash
set -e #任何命令出错就退出
set -o pipefailAPP_IDmy-boot
APP_DIR/data/appnohup java -jar ${APP_DIR}/${APP_ID}/${APP_ID}.jar release_out.log
start_okfalse
if [[ $? 0 ]];thensleep 3tail -n 10 release_out.logsleep 5tail -n 50 release_out.log
fi
aaagrep Started release_out.log | awk {print $1}
if [[ -n ${aaa} ]];thenecho Application started okexit 0
elseecho Application started errorexit 1
fi
在/data/app/my-boot目录下创建停止脚本stop.sh
$ touch stop.sh
$ vi stop.sh
# 将下面代码粘贴到stop.sh中
#!/bin/bashAPP_IDmy-boot
ps aux | grep ${APP_ID} | grep -v grep | awk {print kill -9 $2} | sh
并进行启动和停止测试查看日志输出是否正常
将下述启动代码配置jenkins中
sh $DIR/${projectName}/stop.sh
sh $DIR/${projectName}/start.sh
访问并测试代码是否生效
如果是虚拟机则需要给防火墙添加9010端口
$ su root
# 开启防火墙9010端口
$ firewall-cmd --zonepublic --add-port9010/tcp --permanent
# 使配置生效
$ firewall-cmd --reload
修改代码返回值提交至Gitee并再次进行构建发布访问http://192.168.223.129:9010查看结果是否更新 PS:异常修复 如出现jenkins内存占用异常重启等方法都不能解决时 创建一个新的jenkins_home
mkdir -p /mnt/data/jenkins_home_bak/secrets /mnt/data/jenkins_home_bak/users /mnt/data/jenkins_home_bak/jobscp -a jobs users credentials.xml config.xml plugins tools /mnt/data/jenkins_home_bak/
cp -a secrets/hudson.util.Secret /mnt/data/jenkins_home_bak/secrets/
cp -a jenkins.model.*.xml hudson.tasks.*.xml /mnt/data/jenkins_home_bak/
cp -a hudson.plugins.git.GitTool.xml /mnt/data/jenkins_home_bak/
cp -a io.jenkins.plugins.gitlabserverconfig.servers.GitLabServers.xml /mnt/data/jenkins_home_bak/
cp -a jenkins.plugins.nodejs.tools.NodeJSInstallation.xml /mnt/data/jenkins_home_bak/
cp -a hudson.plugins.gradle.Gradle.xml /mnt/data/jenkins_home_bak/cp /mnt/data/jenkins_home/jenkins.install.InstallUtil.lastExecVersion /mnt/data/jenkins_home_bak/
cp /mnt/data/jenkins_home/jenkins.install.UpgradeWizard.state /mnt/data/jenkins_home_bak/