引言:很久没有认真的写一篇分享了,今天记录一下处理Jenkins Master和Slave之间连接中断的时候的如何预警的问题。

背景

我们基于Jenkins有一系列的持续集成工作,类如打包,API可达性监控,Gerrit Code Verify等等,但是经过这么长时间的观察,我发现Jenkins master经过一段时间就会有报错,
导致我们的Slave和Master连接中断,这个时候,所有的Nodes都会出现Offline。

我特意找了一下,没注意到Jenkins的插件可以检测并随时监控反馈Offline的问题预警。所以想通过自己的方式解决。

确认有无判断OFFLINE出现的API

通过寻找,确认https://<Jenkins域名>/computer/<Slave name>/api/json,这里有查找Slave和Master断连接的信息。只截取我需要的内容

{
"numExecutors": 4,
"offline": false,
"offlineCause": null,
"offlineCauseReason": "",
"oneOffExecutors": [ ],
"temporarilyOffline": false
}

可以看到这里的offline的字段是False,说明连接是正常的,当Offline的值是True的时候,就可以预警了。

解决方案

#!/bin/bash

JENKINS_URL="xxx"
JENKINS_NODE_MAC=`hostname -s | cut -d'0' -f1`
JENKINS_NODE_NR=`hostname -s | cut -d'0' -f2`

# 关注一下Jenkins设置,Nodename是什么
JENKINS_NODENAME="${JENKINS_NODE_MAC}"0"${JENKINS_NODE_NR}"
CHECKED=`curl -u xxx:xxx --silent \
$JENKINS_URL/computer/$JENKINS_NODENAME/api/json | grep -o '"offline":true' |\
cut -d':' -f2`

if [[ "$CHECKED" == "true" ]]; then
echo "INFO: $JENKINS_NODENAME was offline and trigger Python Mail Script"
# 执行预警操作
exit 0
fi
echo "INFO: $JENKINS_NODENAME is online, no need to restart."
exit 0

之前的思路是通过Mac内自带的iMessage,然后编写了脚本,操作分为两步:
先编写一个iMessage.applescript

#!/usr/bin/osascript
on run {targetBuddyPhone, targetMessage}
tell application "Messages"
set targetService to 1st service whose service type = iMessage
set targetBuddy to buddy targetBuddyPhone of targetService
send targetMessage to targetBuddy
end tell
end run

然后调用osascript jenkins.applescript +86-xxx-xxxx-xxxx "Slave连接中断"
奇怪的是iMessage,一直连接不了,我试了各种方式,升级系统,重新登录账号,我确认脚本没有问题,但是iMessage就是连接登录不了。没办法,还是通过邮件吧。

由于公司的自带邮箱是Office 365,那么编写一个可以发邮件的脚本就解决了。

#coding=utf-8

import smtplib
from email.mime.text import MIMEText
from email.header import Header
import datetime

mail_host = "smtp.xxx.xxx" # 设置服务器
mail_user = "xxxx" # 用户名
mail_pass = "xxxx" # 口令

sender = 'xxxx'
receivers = ['xxxx'] # 接收邮件

content = "请注意:"+str(datetime.datetime.now().strftime("%Y-%m-%d
%H:%M:%S"
))+'JenkinsSlave连接断开,请及时处理'

message = MIMEText(content, 'plain', 'utf-8')
message['From'] = Header("注意Jenkins Master Slave连接出错", 'utf-8')
message['To'] = Header("持续集成处理", 'utf-8')

subject = "预警!!!!!!!!!!"
message['Subject'] = Header(subject, 'utf-8')

try:
smtpObj = smtplib.SMTP(mail_host, 587)
smtpObj.ehlo()
smtpObj.starttls()
smtpObj.ehlo
smtpObj.login(mail_user, mail_pass)
smtpObj.sendmail(sender, receivers, message.as_string())
print "邮件发送成功"
except smtplib.SMTPException:
print "Error: 无法发送邮件"

同样的,只要在轮询执行*/5 * * * * sh /Users/xx/Documents/check.sh中,加入调用发送邮件的脚本,就解决了。

写在最后

维护持续集成的稳定,还是一件很繁琐的事情,需要更多的耐心。

虽然这件事很简单,我不清楚是否有更好的方案,也希望知道的可以给我指一条路,谢谢了。


↙↙↙阅读原文可查看相关链接,并与作者交流