前言
非技術分享,僅作為工作交接的備忘錄
一、安裝Jenkins
- 打開官網https://jenkins.io/ 下載下傳得到jenkins.war;
- 建立目錄:mkdir -p /data/deploy/jenkins;
- 将jenkins.war上傳到此目錄;
- 将如下腳本儲存成sh腳本,放到jenkins目錄;
- 給啟動腳本與停止腳本可執行權限:
啟動腳本:startJenkins.sh
# 采用jdk1.8版本,當jdk小于1.7時,XX:MetaspaceSize/XX:MaxMetaspaceSize參數需要替換或直接删除
# jenkins運作在8001端口
#/bin/sh
nohup java -XX:MetaspaceSize=m -XX:MaxMetaspaceSize=m -Xmx2048M -jar jenkins.war --httpPort= &
停止腳本:killJenkins.sh
#!/bin/sh
PID=`lsof -i:|grep -v PID|awk '{print $2}'`
if [[ "x${PID}" == "x" ]]
then
echo "沒有找到運作的程序,不需要結束"
else
echo "目前程序PID:${PID},結束目前程序"
kill - ${PID}
fi
二、建立Jenkins Job
添加新的Job時建議從已經有Job中複制
1. 建立自由風格的Job;
2. 填寫項目配置:
【General】
項目名稱: 根據實際填寫
項目描述:留白或根據實際填寫
GitLab Connection: 留白
丢棄舊的建構:保持建構的最大個數:通常填5
其餘項都可以留白
【源碼管理】
選擇Git, 填寫Repository URL/Branch Specifier
【建構觸發器】
勾選:Poll SCM
填寫:【/5 * * *】
![](https://img.laitimes.com/img/_0nNw4CM6IyYiwiM6ICdiwiI0NXYFhGd192UvwVe0lmdhJ3ZvwFM38CXlZHbvN3cpR2Lc1TPB10QGtWUCpEMJ9CXsxWam9CXwADNvwVZ6l2c052bm9CXUJDT1wkNhVzLcRnbvZ2Lc1TP350MNpWT4VFWlZXUYpVd1kmYr50MZV3YyI2cKJDT29GRjBjUIF2LcRHelR3LcJzLctmch1mclRXY39DO4UTMyETNwEDOwITM3EDMy8CX0Vmbu4GZzNmLn9Gbi1yZtl2Lc9CX6MHc0RHaiojIsJye.jpg)
解釋說明:每5分鐘通路一次git庫,如果有更新則自動觸發打包,如果沒有更新則忽略
【建構環境】
勾選:Color ANSI Console Output
在 ANSI color map中選擇:xterm
【建構】
三、jenkins建構步驟解析
當job運作時會依次執行以下步驟:
1. 檢查git庫上相應的分支是否有更新,如果沒有則直接結束,如果有更新則觸發Job建構;
2. 從git庫上拉取最新的代碼;
3. 運作建構指令,比如:gradle clean build dist;
4. 運作自定義腳本:/data/scripts/gralde.py,gradle腳本中完成将dist指令輸出的目錄打包成zip檔案,并推送到應用伺服器上,解壓替換老版程式;
5. 應用伺服器上定時任務(/data/deploy/daemon.sh)監控程式是否更新,發現更新時自動重新開機應用;
四、gradle腳本詳解
#!/usr/bin/env python
# coding:utf-8
from shutil import rmtree
from subprocess import Popen, PIPE, STDOUT
from os.path import exists, join
from os import environ
from fabric.api import run, put, settings, cd, prefix
from fabric.colors import *
from deng.tools import Tools
ROOT_DIR = environ["WORKSPACE"]
JOB_NAME = environ["JOB_NAME"].replace(
"sit-", "").replace("uat-", "").replace("prod-", "")
# 應用伺服器
APP_SERVER = "fhgk-db"
# 應用部署路徑
APP_PATH = "/data/deploy"
def analy_subproject(filename="settings.gradle"):
"""用途:分析項目,獲得子項目名稱
:param filename: 項目清單定義檔案
:return: 子項目清單
"""
subprojects = []
if os.path.isfile(os.path.join(ROOT_DIR, filename)):
fileobj = open(filename)
else:
print red("{}項目找不到檔案:{}".format(JOB_NAME,
os.path.join(ROOT_DIR, filename)))
exit()
return []
for lines in fileobj.readlines():
if lines.strip().lower().startswith("include"):
project_name = lines.strip().strip("include").strip().strip("\"")
subprojects.append(project_name)
print blue("{}項目包含以下子項目:".format(JOB_NAME))
Tools.format_print(subprojects)
return subprojects
def analy_mainproject(subprojects=None):
"""用途:從衆多子項目中分析出子主項目
:param subprojects: 子項目清單
:return: 主子項目
"""
if subprojects is None:
subprojects = analy_subproject()
for project in subprojects:
if os.path.isdir(os.path.join(ROOT_DIR,
project,
"build/distributions")):
print blue("項目【{}】中【{}】為主子項目".format(JOB_NAME, project))
return project
print red("項目【{}】找不到主子項目,請檢查!".format(JOB_NAME))
exit()
def deploy():
"""用途:部署應用
"""
package = None
app_dir = None
mainproject = analy_mainproject()
global APP_PATH
APP_PATH = APP_PATH+'/'+mainproject
for file in os.listdir(os.path.join(ROOT_DIR,
mainproject,
"build/distributions")):
if file.startswith(mainproject) and file.endswith('.zip'):
package = os.path.join(ROOT_DIR,
mainproject,
"build/distributions",
file)
print blue("本次打包生成安裝包路徑:\n{}".format(package))
break
if package is None:
print red("找不到安裝包:【{}】,請檢查!".format(mainproject + '*.zip'))
exit()
else:
app_pack = os.path.basename(package)
app_dir = os.path.basename(package).split('.zip')[]
with settings(forward_agend=True,
use_ssh_config=True,
host_string=APP_SERVER,
colorize_errors=True):
run("mkdir -p {}".format(APP_PATH))
with cd(APP_PATH):
print blue("删除原有舊版程式:")
run("rm -rf *")
print blue("推送新安裝包到應用伺服器:\n{}".format(APP_PATH))
put(package, APP_PATH)
print blue("開始解壓新包:")
run("unzip -q {}".format(app_pack))
print blue("設定腳本權限:")
run("chmod -R 755 ./bin/*")
run("rm -rf {}".format(app_pack))
# print blue("kill 原進程:")
# run("../kill.sh {}".format(mainproject), shell=False)
if __name__ == "__main__":
deploy()
五、定時任務daemon.sh詳解
說明:采用jenkins來重新開機應用時總是碰到問題,job任務建構完成後,應用程序也自動被kill掉了,找了網上很多資料,但一直沒有解決,是以自己寫了個簡要定時任務來監控應用。
定時任務運作方式:nohup ./daemon.sh &
#!/bin/bash
while true
do
echo `date`
# 需要監控的應用目錄,添加新程式時将應用目錄添加到apps資料中
APPS=("agw-app" "bns-app" "fohowe-urm-app" "fohowe-web-ec" "register_center")
# 周遊每個應用
for APP in ${APPS[@]}
do
cd /data/deploy/${APP}
# 擷取應用的程序ID
PID=`ps -ef|grep /data/deploy/${APP}|grep -v grep|awk '{print $2}'`
if [[ "x${PID}" == "x" ]]
then
echo "${APP}程式沒有運作,重新啟動......"
bin/start.sh &
else
# pid檔案不存在時,說明應用有更新,重新開機
if [[ -f "${APP}.pid" ]]
then
echo "${APP}程序正常:${PID}"
else
echo "${APP}程式找不到PID檔案,重新啟動......"
# kill -9 ${PID}
ps -ef|grep /data/deploy/${APP}|grep -v grep|awk '{print $2}'|xargs kill -
bin/start.sh &
fi
fi
done
# 每次循環60秒
sleep
echo ""
done