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中的沒有郵箱認證步驟,因此這裏的腳本增加了郵箱認證):
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)
linux+Git+Maven+Jenkins+Neuxs自動化編譯環境搭建
CentOS6安裝Jenkins
使用Jenkins配置Git+Maven的自動化構建
Jenkins+Maven+Git搭建持續集成和自動化部署的配置手記
Jenkins的分布式構建及部署——節點
本文永久更新鏈接地址:
Tags: execution machines Windows checkout command
文章來源: