一窄绒、問(wèn)題
通過(guò)jenkins執(zhí)行shell腳本時(shí)沐鼠,腳本中是通過(guò)nohup java -jar &的方式啟動(dòng)肝箱,顯示執(zhí)行成功,但是服務(wù)卻沒(méi)啟動(dòng),腳本如下:
#! /bin/bash
nohup java -Xms800m -Xmx800m -XX:PermSize=256m -XX:MaxPermSize=512m -XX:MaxNewSize=512m -jar /usr/local/joshua317-test-core-1.0-SNAPSHOT.jar &
也就是說(shuō)當(dāng)通過(guò)Jenkins構(gòu)建完后推送到業(yè)務(wù)服務(wù)器绵载,在執(zhí)行腳本時(shí)拥坛,腳本中的 nohup 命令無(wú)法正常退出,構(gòu)建前臺(tái)任務(wù)就卡住了尘分,或者是nohup總是無(wú)效猜惋。
二、排查
1.在業(yè)務(wù)服務(wù)器上直接執(zhí)行腳本培愁,可以正常運(yùn)行著摔,說(shuō)明腳本的問(wèn)題不大,但是一旦結(jié)合jenkins進(jìn)行發(fā)布定续,雖然jenkins顯示成功谍咆,但是shell腳本并沒(méi)有執(zhí)行。
2.找一個(gè)簡(jiǎn)單的腳本進(jìn)行測(cè)試
#! /bin/bash
echo "hello" >> /usr/local/test.txt
/usr/local/test.txt中有內(nèi)容私股,說(shuō)明腳本是可以執(zhí)行成功摹察,同時(shí)也說(shuō)明jenkins在執(zhí)行帶有nohup腳本的時(shí)候出現(xiàn)了問(wèn)題。也就是說(shuō)構(gòu)建命令中如果帶有 nohup xxx &
觸發(fā)構(gòu)建后并構(gòu)建成功后,雖然但在構(gòu)建任務(wù)的輸出中卻顯示沒(méi)有問(wèn)題,也沒(méi)有任何報(bào)錯(cuò)倡鲸,但是并沒(méi)有執(zhí)行shell腳本供嚎。
三、原因
jenkins默認(rèn)會(huì)在構(gòu)建完成后峭状,殺掉構(gòu)建過(guò)程中由shell命令觸發(fā)的衍生進(jìn)程克滴。
jenkins根據(jù)BUILD_ID識(shí)別某個(gè)進(jìn)程是否為構(gòu)建過(guò)程的衍生進(jìn)程,故修改BUILD_ID后优床,jenkins就無(wú)法識(shí)別是否為衍生進(jìn)程劝赔,則此進(jìn)程能在后臺(tái)保留運(yùn)行。
結(jié)論就是Jenkins程序只負(fù)責(zé)運(yùn)行偽命令行nuhup 命令胆敞,并不保證是否成功運(yùn)行 nuhup后面的命令着帽。
四杂伟、解決
(1)使用 BUILD_ID=xxx
,其中xxx可以是任意內(nèi)容(只要不是原來(lái)的BUILD_ID內(nèi)容即可),同時(shí)需要把nohup輸出內(nèi)容重定向到文件里面,如"/usr/local/nohup.out"
#! /bin/bash
BUILD_ID=dontKillMe
nohup java -Xms800m -Xmx800m -XX:PermSize=256m -XX:MaxPermSize=512m -XX:MaxNewSize=512m -jar /usr/local/joshua317-test-core-1.0-SNAPSHOT.jar > /usr/local/nohup.out 2>&1 &
(2)使用at now代替nohup命令仍翰。
#! /bin/bash
#so "at now" will run even if java -jar fails
set +e
#Run java app in background
echo "java -jar /usr/local/joshua317-test-core-1.0-SNAPSHOT.jar" | at now
set -e : 執(zhí)行的時(shí)候如果出現(xiàn)了返回值為非零赫粥,整個(gè)腳本 就會(huì)立即退出
set +e: 執(zhí)行的時(shí)候如果出現(xiàn)了返回值為非零將會(huì)繼續(xù)執(zhí)行下面的腳本
五、擴(kuò)展
1.Jenkins里執(zhí)行shell腳本時(shí)歉备,要注意使用全路徑
/bin/sh /usr/local/service/start.sh
2.shell腳本文件的第一行要聲明是shell腳本
#! /bin/bash
....
3.使用jenkins執(zhí)行shell腳本時(shí)傅是,如果有nohup命令時(shí)匪燕,需要加上BUILD_ID=dontKillMe
以及nohup后面
需要后面加上2>&1 &
注意:BUILD_ID=后面可以是其他內(nèi)容蕾羊,比如BUILD_ID=joshua317
#! /bin/bash
BUILD_ID=dontKillMe
nohup java -Xms800m -Xmx800m -XX:PermSize=256m -XX:MaxPermSize=512m -XX:MaxNewSize=512m -jar /usr/local/joshua317-test-core-1.0-SNAPSHOT.jar > /usr/local/nohup.out 2>&1 &
4.如果遇到[Build step 'Send files or execute commands over SSH' changed build result to UNSTABLE]
基本上是因?yàn)閟hell腳本寫(xiě)的有問(wèn)題。
5.關(guān)于nohup后面加上的說(shuō)明
(1)命令結(jié)尾沒(méi)有 "&"帽驯,則變成 "java -jar xxx.jar" 龟再,表示在當(dāng)前shell窗口,可按CTRL + C打斷程序運(yùn)行尼变,或者直接關(guān)閉窗口利凑,則程序直接退出
命令結(jié)尾添加 "&" ,則變成 "java -jar xxx.jar &"嫌术,表示在當(dāng)窗口關(guān)閉時(shí)哀澈,程序才會(huì)中止運(yùn)行。&代表讓該命令在后臺(tái)執(zhí)行度气。
java -jar /usr/local/joshua317-test-core-1.0-SNAPSHOT.jar &
(2)命令 "nohup java -jar xxx.jar &"部分割按,表示不掛斷運(yùn)行命令,當(dāng)賬戶退出或終端關(guān)閉時(shí),程序仍然運(yùn)行。注意磷籍,該作業(yè)的所有輸出被重定向到nohup.out的文件中适荣。
命令 “nohup java -jar xxx.jar > nohup.out &” 部分,表示不掛斷運(yùn)行命令,當(dāng)賬戶退出或終端關(guān)閉時(shí),程序仍然運(yùn)行院领,并且該作業(yè)的所有輸出被重定向到nohup.out的文件中弛矛。“ > nohup.out ” 該命令就是指定日志輸出的文件比然。
">>"表示將輸出以追加的方式重定向到nohup.out中丈氓。
nohup java -jar /usr/local/joshua317-test-core-1.0-SNAPSHOT.jar > /usr/local/nohup.out &
#或者
nohup java -jar /usr/local/joshua317-test-core-1.0-SNAPSHOT.jar >> /usr/local/nohup.out &
(3)標(biāo)準(zhǔn)輸入文件(stdin):stdin的文件描述符為0,Unix程序默認(rèn)從stdin讀取數(shù)據(jù)强法。
標(biāo)準(zhǔn)輸出文件(stdout):stdout 的文件描述符為1扒寄,Unix程序默認(rèn)向stdout輸出數(shù)據(jù)。
標(biāo)準(zhǔn)錯(cuò)誤文件(stderr):stderr的文件描述符為2拟烫,Unix程序會(huì)向stderr流中寫(xiě)入錯(cuò)誤信息该编。
屏蔽輸出,起到禁止輸出作用:/dev/null 是一個(gè)特殊的文件硕淑,寫(xiě)入到它的內(nèi)容都會(huì)被丟棄课竣;如果嘗試從該文件讀取內(nèi)容嘉赎,那么什么也讀不到。但是 /dev/null 文件非常有用于樟,將命令的輸出重定向到它公条,會(huì)起到"禁止輸出"的效果∮厍“> /usr/local/nohup.out 2>&1” :表示將 stdout 和 stderr 合并后重定向到"/usr/local/nohup.out"中靶橱。
nohup java -jar /usr/local/joshua317-test-core-1.0-SNAPSHOT.jar > /usr/local/nohup.out 2>&1 &
或者
nohup java -jar /usr/local/joshua317-test-core-1.0-SNAPSHOT.jar >> /usr/local/nohup.out 2>&1 &
或者
nohup java -jar /usr/local/joshua317-test-core-1.0-SNAPSHOT.jar > /dev/null 2>&1 &
6.linux的at一次性定時(shí)任務(wù)的使用
使用at只能執(zhí)行一次性任務(wù);使用at命令需要開(kāi)啟atd進(jìn)程路捧。
(1)安裝at命令:
查看是否開(kāi)啟atd進(jìn)程:
ps -ef | grep atd
如果沒(méi)有需要安裝at命令
yum -y install at
(2)設(shè)置自動(dòng)啟動(dòng)at命令
chkconfig --level 35 atd on
(3)啟動(dòng)atd進(jìn)程
service atd start
如果在使用at命令后关霸,報(bào)如下錯(cuò)誤:
Can't open /var/run/atd.pid to signal atd. No atd running?
意思是atd進(jìn)程沒(méi)有運(yùn)行,需要執(zhí)行啟動(dòng)atd進(jìn)程命令:service atd start
(4)簡(jiǎn)單的使用
#1.顯示版本信息
at -V
#2.查看延時(shí)任務(wù)列表
at -l
#3.查看任務(wù)內(nèi)容
at -c 任務(wù)號(hào)
#4.刪除任務(wù)
at -r 任務(wù)號(hào)
#5. now +時(shí)間杰扫,時(shí)間以minutes队寇、hours、days或weeks為單位章姓,比如“now +5 days”代表命令在5天之后的此時(shí)此刻執(zhí)行
#(1)立即執(zhí)行
at now
#(2)一分鐘后執(zhí)行
at now +1min
#(3)五天后執(zhí)行
at now +5 days
#(4)設(shè)置5天后晚上00:00執(zhí)行
at 00:00 +5 days
#(5)設(shè)置在2022年7月20號(hào)凌晨01:00執(zhí)行
at 01::00 2022-7-20
#6.管道方式執(zhí)行一次任務(wù)
echo hello>/usr/local/at.txt|at now