Jenkins分布式构建

本文介绍如何配置Jenkins实现分布式构建,包括Master与Slave节点配置、Job配置及节点监控方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

https://i-blog.csdnimg.cn/blog_migrate/153bb53cf33c65c19fc83beb36595533.png

Jenkins分布式构建(Jenkins Distributed builds)

前言:

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

一、Jenkins节点配置

1.Master配置

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

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

3)点击“新建节点”





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

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

其中启动方法有四种:



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节点配置


当节点以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连接


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

二、Job配置


        在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构建步骤:



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

  1. <span style="font-size: 13px;">import hudson.model.*  
  2. import hudson.node_monitors.*  
  3. import hudson.slaves.*  
  4. import java.util.concurrent.*  
  5.   
  6. jenkins = Hudson.instance  
  7.   
  8. import javax.mail.internet.*;  
  9. import javax.mail.*  
  10. import javax.activation.*  
  11.   
  12.   
  13. def sendMail (slave, cause) {  
  14.   //这里使用的是参数化构建中的变量,如果不使用此方式,可以注释掉,而使用下面的toAddress  
  15.  toAddress = build.buildVariableResolver.resolve("EMAIL_RECEIVERS")  
  16.     
  17.  message = slave + " slave is down. Check http://192.168.10.181:8080/jenkins/computer/" + slave + "\nBecause " + cause  
  18.  subject = "【jenkins节点监控】" + slave + " slave is offline"  
  19.  //toAddress = "***@***.com;***@***.com"  
  20.  fromAddress = "***@***.com"  
  21.  host = "SMTP_SERVER"  
  22.  port = "SMTP_PORT"  
  23.   
  24.  Properties props = new Properties();  
  25.  // 发送邮件的服务器  
  26.  props.setProperty("mail.smtp.host""smtp.***.com");  
  27.  // 发送邮件的协议  
  28.  props.setProperty("mail.transport.protocol""smtp");  
  29.  // 在连接服务器的时候是否需要验证,发邮件是需要验证的  
  30.  props.setProperty("mail.smtp.auth""true");  
  31.     
  32.  // 当需要进行验证的时候,会自动从Session中去取该Authenticator对象  
  33.  Authenticator authenticator = new Authenticator() {  
  34.       
  35.    @Override  
  36.    protected PasswordAuthentication getPasswordAuthentication() {  
  37.      return new PasswordAuthentication("your user name""your passwd"); //输入用户名、密码  
  38.    }  
  39.       
  40.  };  
  41.   
  42.  Session lSession = Session.getInstance(props,authenticator);  
  43.  MimeMessage msg = new MimeMessage(lSession);  
  44.   
  45.   
  46.  //tokenize out the recipients in case they came in as a list  
  47.  StringTokenizer tok = new StringTokenizer(toAddress,";");  
  48.  ArrayList emailTos = new ArrayList();  
  49.  while(tok.hasMoreElements()){  
  50.  emailTos.add(new InternetAddress(tok.nextElement().toString()));  
  51.  }  
  52.  InternetAddress[] to = new InternetAddress[emailTos.size()];  
  53.  to = (InternetAddress[]) emailTos.toArray(to);  
  54.   
  55.     
  56.  msg.setRecipients(MimeMessage.RecipientType.TO,to);  
  57.  InternetAddress fromAddr = new InternetAddress(fromAddress);  
  58.  msg.setFrom(fromAddr);  
  59.  msg.setFrom(new InternetAddress(fromAddress));  
  60.  msg.setSubject(subject);  
  61.  msg.setText(message)  
  62.   
  63.  Transport transporter = lSession.getTransport("smtp");  
  64.  transporter.connect();  
  65.  transporter.send(msg);  
  66. }  
  67.   
  68.   
  69. def getEnviron(computer) {  
  70.    def env  
  71.    def thread = Thread.start("Getting env from ${computer.name}", { env = computer.environment })  
  72.    thread.join(2000)  
  73.    if (thread.isAlive()) thread.interrupt()  
  74.    env  
  75. }  
  76.   
  77. def slaveAccessible(computer) {  
  78.     getEnviron(computer)?.get('PATH') != null  
  79. }  
  80.   
  81.   
  82. def numberOfflineNodes = 0  
  83. def numberNodes = 0  
  84. for (slave in jenkins.slaves) {  
  85.    def computer = slave.computer  
  86.    numberNodes ++  
  87.    println ""  
  88.    println "Checking computer ${computer.name}:"  
  89.    def isOK = (slaveAccessible(computer) && !computer.offline)  
  90.    if (isOK) {  
  91.      println "\t\tOK, got PATH back from slave ${computer.name}."  
  92.      println('\tcomputer.isOffline: ' + slave.getComputer().isOffline());   
  93.      println('\tcomputer.isTemporarilyOffline: ' + slave.getComputer().isTemporarilyOffline());  
  94.      println('\tcomputer.getOfflineCause: ' + slave.getComputer().getOfflineCause());  
  95.      println('\tcomputer.offline: ' + computer.offline);   
  96.        
  97.        
  98.    } else {  
  99.      numberOfflineNodes ++  
  100.      println "  ERROR: can't get PATH from slave ${computer.name}."  
  101.      println('\tcomputer.isOffline: ' + slave.getComputer().isOffline());   
  102.      println('\tcomputer.isTemporarilyOffline: ' + slave.getComputer().isTemporarilyOffline());  
  103.      println('\tcomputer.getOfflineCause: ' + slave.getComputer().getOfflineCause());  
  104.      println('\tcomputer.offline: ' + computer.offline);   
  105.      sendMail(computer.name, slave.getComputer().getOfflineCause().toString())  
  106.      if (slave.getComputer().isTemporarilyOffline()) {  
  107.       if (!slave.getComputer().getOfflineCause().toString().contains("Disconnected by")) {  
  108.          computer.setTemporarilyOffline(false, slave.getComputer().getOfflineCause())          
  109.       }  
  110.      } else {  
  111.          computer.connect(true)    
  112.      }  
  113.    }  
  114.  }  
  115. println ("Number of Offline Nodes: " + numberOfflineNodes)  
  116. println ("Number of Nodes: " + numberNodes)  </span><span style="font-size:14px;">  
  117. </span>  
注: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以上的版本
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值