阿里云-云小站(无限量代金券发放中)
【腾讯云】云服务器、云数据库、COS、CDN、短信等热卖云产品特惠抢购

Jenkins分布式构建

157次阅读
没有评论

共计 6096 个字符,预计需要花费 16 分钟才能阅读完成。

Jenkins 分布式构建(Jenkins Distributed builds)

前言:

当自动化测试用例需要在多个 PC 机或虚拟机中执行时,如果在每个虚拟机中均搭建类似 tomcat+jenkins 的环境,将会造成例如每台虚拟机资源占用大、对环境的配置维护成本大等弊端,此时,就可以采用 Jenkins 分布式构建方式了。

一、Jenkins 节点配置

1.Master 配置

1)进入 Master 的 http://ip:8080/jenkins/ 网页界面

2)进入系统管理——节点管理界面

3)点击“新建节点”

Jenkins 分布式构建


 

远程工作目录:指定远程中的节点机器的工作目录,即 Job 中 checkout 出的代码所在的 workspace 目录

标签:该节点的唯一标识,当在 Job 中要指定只在该节点进行构建与测试时,通过该唯一标识进行指定

其中启动方法有四种:

Jenkins 分布式构建

Launch slave agents on Unix machines via SSH:当节点为 Unix slaves 时,可以选择此种方式

Launch slave agents via Java Web Start:使用 JNLP 方式来建立 slave 与 master 的连接

Launch slave via execution of command on the Master:使用命令行方式

Let Jenkins control this Windows slave as a Windows service:Jenkins 将把该 Windows slave 当做 Windows service 进行控制

对于 Windows 操作系统的节点,推荐用第二种 Launch slave agents via Java Web Start

点击“保存”后,在 Master 中一个节点就配置好了

2.slave 节点配置

Jenkins 分布式构建

当节点以 Launch slaveagents via Java Web Start 配置好后,在节点界面将看到如图所示,其 slave 有三种启动方法,本质上其实就一种,即将 master 中的 slave-agetn.jnlp 文件下载至 slave 所在的虚拟机,然后运行文件。

注:上图中 Run from slave command line 中的 ip 地址,如果在 jenkins 系统配置界面中没设置过 ip 的话,将为 localhost,因此此时需要自己先查看下自己 master 机器的 ip。

因此为方便,可以将连接方式写入 bat 批处理文件中。

1)进入节点虚拟机,先创建刚才配置的远程工作目录(D:\\jenkins)

2)创建 bat 文件,命令为例如:start_jenkins_agent.bat  内容:

javaws http://192.168.10.181:8080/jenkins/computer/Windows_181_to_4400/slave-agent.jnlp

3)双击运行文件即可看到 slave 节点与 master 连接

Jenkins 分布式构建Jenkins 分布式构建

注:上图中,点击 File——Installas a services  可以将该 slave agent 以 Windows 系统服务运行,理论上方便于开机自启动,但作为 Windows 服务,是无法与 GUI 进行交互的,因此没法启动火狐进行 selenium 的自动化测试,因此如果自动化测试与 GUI 相关,这里千万别 Install as a services。

二、Job 配置

Jenkins 分布式构建        在 Master 中新建一个 job,其中在配置页面中勾选 Restrict when this project can be run,Label 选择要在哪个节点中运行,这样就可以指定该 job 在哪个 slave 节点中运行了

三、Jenkins slave 开机自启动

1)若要对所用用户均进行开机自启动,则将.bat 启动文件的快捷方式放入‘\Documents and Settings\All Users\“开始”菜单 \ 程序 \ 启动’目录下

2)若只要对指定用户进行开机自启动,则将.bat 启动文件的快捷方式放入‘\Documents and Settings\ < 用户名字 >\“开始”菜单 \ 程序 \ 启动’目录下

四、Jenkins 节点监控

jenkins 节点由于系统运行、网络环境等各种因素,难免会出现系统挂机、节点掉线等情况,因此要想及时发现这些情况,就需要对节点进行监控,

可以采用这里推荐的监控并重连机制:https://wiki.jenkins-ci.org/display/JENKINS/Monitor+and+Restart+Offline+Slaves

1)由于 jenkins 节点监控使用的是 groovy 脚本调用的 jenkins 内部 api,因此需要先安装 groovy plugin 插件

2)在 Master 中新建一个名字为如 monitor 的 job,设置为例如每 30 分钟运行一次。

3)新增 Excute system Groovy script 构建步骤:

Jenkins 分布式构建

输入 groovy 脚本(由于 wiki 中的没有邮箱认证步骤,因此这里的脚本增加了邮箱认证):

import hudson.model.*
import hudson.node_monitors.*
import hudson.slaves.*
import java.util.concurrent.*

jenkins = Hudson.instance

import javax.mail.internet.*;
import javax.mail.*
import javax.activation.*


def sendMail (slave, cause) {
  // 这里使用的是参数化构建中的变量,如果不使用此方式,可以注释掉,而使用下面的 toAddress
 toAddress = build.buildVariableResolver.resolve("EMAIL_RECEIVERS")
  
 message = slave + "slave is down. Check http://192.168.10.181:8080/jenkins/computer/" + slave + "\nBecause" + cause
 subject = "【jenkins 节点监控】" + slave + "slave is offline"
 //toAddress = "***@***.com;***@***.com"
 fromAddress = "***@***.com"
 host = "SMTP_SERVER"
 port = "SMTP_PORT"

 Properties props = new Properties();
 // 发送邮件的服务器
 props.setProperty("mail.smtp.host", "smtp.***.com");
 // 发送邮件的协议
 props.setProperty("mail.transport.protocol", "smtp");
 // 在连接服务器的时候是否需要验证,发邮件是需要验证的
 props.setProperty("mail.smtp.auth", "true");
  
 // 当需要进行验证的时候,会自动从 Session 中去取该 Authenticator 对象
 Authenticator authenticator = new Authenticator() {
    
   @Override
   protected PasswordAuthentication getPasswordAuthentication() {return new PasswordAuthentication("your user name", "your passwd"); // 输入用户名、密码
   }
    
 };

 Session lSession = Session.getInstance(props,authenticator);
 MimeMessage msg = new MimeMessage(lSession);


 //tokenize out the recipients in case they came in as a list
 StringTokenizer tok = new StringTokenizer(toAddress,";");
 ArrayList emailTos = new ArrayList();
 while(tok.hasMoreElements()){emailTos.add(new InternetAddress(tok.nextElement().toString()));
 }
 InternetAddress[] to = new InternetAddress[emailTos.size()];
 to = (InternetAddress[]) emailTos.toArray(to);

  
 msg.setRecipients(MimeMessage.RecipientType.TO,to);
 InternetAddress fromAddr = new InternetAddress(fromAddress);
 msg.setFrom(fromAddr);
 msg.setFrom(new InternetAddress(fromAddress));
 msg.setSubject(subject);
 msg.setText(message)

 Transport transporter = lSession.getTransport("smtp");
 transporter.connect();
 transporter.send(msg);
}


def getEnviron(computer) {
   def env
   def thread = Thread.start("Getting env from ${computer.name}", {env = computer.environment})
   thread.join(2000)
   if (thread.isAlive()) thread.interrupt()
   env
}

def slaveAccessible(computer) {getEnviron(computer)?.get('PATH') != null
}


def numberOfflineNodes = 0
def numberNodes = 0
for (slave in jenkins.slaves) {
   def computer = slave.computer
   numberNodes ++
   println ""println"Checking computer ${computer.name}:"
   def isOK = (slaveAccessible(computer) && !computer.offline)
   if (isOK) {println "\t\tOK, got PATH back from slave ${computer.name}."
     println('\tcomputer.isOffline:' + slave.getComputer().isOffline()); 
     println('\tcomputer.isTemporarilyOffline:' + slave.getComputer().isTemporarilyOffline());
     println('\tcomputer.getOfflineCause:' + slave.getComputer().getOfflineCause());
     println('\tcomputer.offline:' + computer.offline); 
     
     
   } else {
     numberOfflineNodes ++
     println "ERROR: can't get PATH from slave ${computer.name}."println('\tcomputer.isOffline: ' + slave.getComputer().isOffline()); 
     println('\tcomputer.isTemporarilyOffline:' + slave.getComputer().isTemporarilyOffline());
     println('\tcomputer.getOfflineCause:' + slave.getComputer().getOfflineCause());
     println('\tcomputer.offline:' + computer.offline); 
     sendMail(computer.name, slave.getComputer().getOfflineCause().toString())
     if (slave.getComputer().isTemporarilyOffline()) {if (!slave.getComputer().getOfflineCause().toString().contains("Disconnected by")) {computer.setTemporarilyOffline(false, slave.getComputer().getOfflineCause())        
      }
     } else {computer.connect(true)  
     }
   }
 }
println ("Number of Offline Nodes:" + numberOfflineNodes)
println ("Number of Nodes:" + numberNodes)

注:jenkins 在 1.582 版本时修复了一个 slave 会概率性出现掉线,且无法重连,只至重启才能再次连接的问题,CancelledKeyException can cause all JNLP slaves to disconnect (and the problem remains until restart):https://issues.jenkins-ci.org/browse/JENKINS-24050

因此建议将 jenkins 升级至最新的或 1.582 以上的版本

 

局域网内利用 GitLab+Jenkins 自动生成 GitBook 并发布 (Nginx)  http://www.linuxidc.com/Linux/2016-05/131136.htm

Linux+Git+Maven+Jenkins+Neuxs 自动化编译环境搭建 http://www.linuxidc.com/Linux/2016-02/128652.htm

CentOS6 安装 Jenkins  http://www.linuxidc.com/Linux/2016-05/131365.htm

使用 Jenkins 配置 Git+Maven 的自动化构建 http://www.linuxidc.com/Linux/2016-02/128641.htm

Jenkins+Maven+Git 搭建持续集成和自动化部署的配置手记 http://www.linuxidc.com/Linux/2015-06/118606.htm

Jenkins 的分布式构建及部署——节点  http://www.linuxidc.com/Linux/2015-05/116903.htm

Jenkins 的详细介绍 :请点这里
Jenkins 的下载地址 :请点这里

本文永久更新链接地址 :http://www.linuxidc.com/Linux/2016-08/133889.htm

正文完
星哥说事-微信公众号
post-qrcode
 0
星锅
版权声明:本站原创文章,由 星锅 于2022-01-21发表,共计6096字。
转载说明:除特殊说明外本站文章皆由CC-4.0协议发布,转载请注明出处。
【腾讯云】推广者专属福利,新客户无门槛领取总价值高达2860元代金券,每种代金券限量500张,先到先得。
阿里云-最新活动爆款每日限量供应
评论(没有评论)
验证码
【腾讯云】云服务器、云数据库、COS、CDN、短信等云产品特惠热卖中