如何使用 groovy 脚本通过 jenkins 管道重新启动应用程序总共 5 次,每次启动之间有 25 分钟的延迟?
//service update command need to execute..
stage('haproxy restart') {
script{
sh '''
docker service update --force abc-haproxy-${qa_env}-haproxy //5 times need to execute, delay between restart is 25 minutes.
'''}
答案1
如果只是重复 5 次,中间有延迟,则只需重复该命令 5 次,中间有睡眠。
//service update command need to execute..
stage('haproxy restart') {
script{
sh '''
docker service update --force abc-haproxy-${qa_env}-haproxy
sleep 25m
docker service update --force abc-haproxy-${qa_env}-haproxy
sleep 25m
docker service update --force abc-haproxy-${qa_env}-haproxy
sleep 25m
docker service update --force abc-haproxy-${qa_env}-haproxy
sleep 25m
docker service update --force abc-haproxy-${qa_env}-haproxy
'''}
gnu sleep 理解25m
为 25 分钟。大多数(如果不是所有)其他睡眠都将数字(如果没有字母)作为秒数。如果系统上的 sleep 无法识别字母,则计算 60 秒乘以 25 分钟并使用该数字。
请注意,如果这样做,整个命令将在整个时间内阻塞(因此至少 4 次 25 分钟加上 docker 命令所花费的时间)。另请注意,我对詹金斯的经验很少。我不知道这对其他管道是否有害。
关于延迟
从上次返回到下次发射有延迟吗?或者从上次启动到下次启动有延迟吗?
如果命令(在本例中为 docker)只需要几秒钟,那么没关系。但如果该命令需要几分钟,那么您就必须处理好这额外的时间。
例如,如果 docker 命令需要大约 5 分钟。那么从第一次启动开始,您有 5 分钟的 docker 运行时间,然后有 25 分钟的睡眠时间,直到下次启动。从发射到发射一共需要30分钟。这个场景就是通过上面的代码得到的。
或者,如果 docker 已经运行了 5 分钟,则仅休眠 20 分钟,从启动到下次启动的总时间为 25 分钟。幸运的是,这在 shell 代码中实现起来相当简单:
//service update command need to execute..
stage('haproxy restart') {
script{
sh '''
docker service update --force abc-haproxy-${qa_env}-haproxy &
sleep 25m
wait
docker service update --force abc-haproxy-${qa_env}-haproxy &
sleep 25m
wait
docker service update --force abc-haproxy-${qa_env}-haproxy &
sleep 25m
wait
docker service update --force abc-haproxy-${qa_env}-haproxy &
sleep 25m
wait
docker service update --force abc-haproxy-${qa_env}-haproxy
'''}
&
末尾的与号 ( ) 使 docker 命令在后台执行。效果是 sleep 将“立即”开始执行,并且将与 docker 命令并行地开始休眠。如果 docker 命令需要 5 分钟,则 sleep 已经休眠 5 分钟,并将继续休眠 20 分钟,从上次启动起总共 25 分钟。
“立即”用引号引起来,因为由于操作系统的簿记等原因,总会有一些微秒的延迟。但在 25 分钟睡眠且仅重复 5 次的情况下,这些应该可以忽略不计。
最后一个 docker 命令没有 & 符号(因此没有后台),因为我们想要等待该命令正确完成。否则,即使最后一个 docker 命令仍在运行(在后台),jenkins 也可能会认为该阶段已完成。同样,我对詹金斯的经验很少,所以不知道其中的复杂细节。
wait 命令使 sh 等待任何后台进程,直到它们完成后再继续下一个命令。它有效地取消了&符号。因此,如果 docker 命令需要花费超过 25 分钟并且睡眠已完成,那么 sh 会等待该 docker 命令返回,然后再开始下一个命令。
否则,无需等待,如果 docker 命令花费的时间超过 25 分钟,则睡眠将完成,下一个 docker 命令将与仍在运行的 docker 命令并行启动。这可能会引起不满,因为并行运行 docker 命令可能会导致系统资源不足。
奖金:
您可以将命令放在 shell 函数中以减少代码重复
//service update command need to execute..
stage('haproxy restart') {
script{
sh '''
dodocker() {
docker service update --force abc-haproxy-$1-haproxy
}
dodocker ${qa_env}
sleep 25m
dodocker ${qa_env}
sleep 25m
dodocker ${qa_env}
sleep 25m
dodocker ${qa_env}
sleep 25m
dodocker ${qa_env}
'''}
您可以编写一个循环,以提高重复次数的灵活性
//service update command need to execute..
stage('haproxy restart') {
script{
sh '''
dodocker() {
docker service update --force abc-haproxy-$1-haproxy
}
seq ${repeat} | while read _ ; do
dodocker ${qa_env}
sleep 25m
done
dodocker ${qa_env}
'''}
注意将重复设置为少一,因为最后一次 dodocker 迭代不在循环中,因为之后它不应该休眠。
您可以将睡眠分阶段进行,以实现人性化的日志输出
//service update command need to execute..
stage('haproxy restart') {
script{
sh '''
dodocker() {
docker service update --force abc-haproxy-$1-haproxy
}
seq ${repeat} | while read r ; do
echo "repeat number $r"
dodocker ${qa_env}
seq ${delay} | while read d ; do
echo "delay minute $d"
sleep 1m
done
done
dodocker ${qa_env}
'''}
这样您就可以跟踪日志文件并查看进程已经运行了多远。毕竟4次25分钟差不多2个小时了。