隨著軟件開(kāi)發(fā)復(fù)雜度的不斷提高,團(tuán)隊(duì)開(kāi)發(fā)成員間如何更好的協(xié)同工作以確保軟件開(kāi)發(fā)的質(zhì)量已經(jīng)成為開(kāi)發(fā)過(guò)程中不可回避的問(wèn)題。尤其是近年來(lái)敏捷開(kāi)發(fā)在軟件領(lǐng)域越來(lái)越火,如何能在不間斷變化的需求中快速適應(yīng)和保證軟件的質(zhì)量顯得尤其重要。持續(xù)集成正是針對(duì)這一問(wèn)題的一種軟件開(kāi)發(fā)實(shí)踐。它倡導(dǎo)團(tuán)隊(duì)開(kāi)發(fā)成員必須經(jīng)常集成他們的工作,甚至每天都可能發(fā)生多次集成。而每次集成都是通過(guò)自動(dòng)化的構(gòu)建來(lái)驗(yàn)證,包括自動(dòng)編譯、發(fā)布和測(cè)試,從而盡快地發(fā)現(xiàn)集成錯(cuò)誤,讓團(tuán)隊(duì)能更快的開(kāi)發(fā)內(nèi)聚的軟件。
Jenkins是一個(gè)開(kāi)源項(xiàng)目,提供了一種易于使用的持續(xù)集成系統(tǒng),使開(kāi)發(fā)者從繁雜的集成中解脫出來(lái),專注于更重要的業(yè)務(wù)邏輯實(shí)現(xiàn)上。同時(shí)Jenkins能實(shí)時(shí)監(jiān)控集成中存在的錯(cuò)誤,提供詳細(xì)的日志文件和提醒功能,還能用圖表的形式形象的展示項(xiàng)目構(gòu)建的趨勢(shì)和穩(wěn)定性。
Jenkins提供了大量的插件,這些插件使Jenkins能實(shí)現(xiàn)很多復(fù)雜的功能。下面列出了部分持續(xù)集成所需的插件:
安裝插件的步驟:在面板界面左側(cè)的導(dǎo)航欄中選擇Manager Jenkins ---> System Configuration ---> Manager Plugins,在插件管理頁(yè)面中點(diǎn)擊“可選插件”選項(xiàng)卡,然后在輸入框中填寫需要安裝的插件名字。
全局工具配置主要對(duì)一些常用工具的名稱、版本、路徑和配置文件進(jìn)行設(shè)定。在面板左側(cè)的導(dǎo)航欄中點(diǎn)擊“系統(tǒng)管理”,進(jìn)入到“管理Jenkins”界面,選擇界面中的System Configuration ---> Global Tool Configuration后進(jìn)入到“全局工具配置”界面,依次對(duì)Maven配置、JDK、Git、Maven、NodeJS、Sonar Scanner等進(jìn)行配置。
主要用于Maven的主配置文件settings.xml的設(shè)定。settings.xml包含倉(cāng)庫(kù)鏡像、本地鏡像和認(rèn)證信息等。一般默認(rèn)的路徑有兩種:Global Maven Settings --- ${M2_HOME}/conf/settings.xml;User Maven Settings --- ${user.HOME}/.m2/settings.xml。如果兩個(gè)文件都存在,會(huì)對(duì)內(nèi)容進(jìn)行合并,優(yōu)先應(yīng)用當(dāng)前目錄下settings.xml中的設(shè)定。
如果已經(jīng)安裝過(guò)JDK,這里需要配置JDK的JAVA_HOME。
Git的配置也很重要,因?yàn)榇蠖鄶?shù)的任務(wù)都要獲取Git倉(cāng)庫(kù)中的代碼,所以這里需要配置Git的執(zhí)行路徑。
主要用于配置Maven的主目錄,可以添加多個(gè),用Name來(lái)區(qū)分。如果系統(tǒng)中已經(jīng)安裝Maven,這里直接填寫MAVEN_HOME對(duì)應(yīng)的路徑,Jenkins會(huì)在Master節(jié)點(diǎn)上進(jìn)行檢查,查看該目錄是否有效。
SonarQube Scanner用于代碼的靜態(tài)質(zhì)量掃描,可以自動(dòng)安裝,也可以手動(dòng)將其安裝在Master服務(wù)器上。這里采用的是自動(dòng)安裝,在“版本”下拉選框中選擇所要安裝的版本號(hào)即可。
NodeJS是一個(gè)JavaScript的運(yùn)行環(huán)境,作為打包工具或者構(gòu)建工具。如果要在Jenkins中實(shí)現(xiàn)編譯、打包前端代碼,則需要安裝此軟件。
在Jenkins主面板左側(cè)的導(dǎo)航欄中選擇“系統(tǒng)管理”,進(jìn)入到“管理Jenkins”界面,點(diǎn)擊此界面中“系統(tǒng)配置”模塊下的“系統(tǒng)配置”選項(xiàng),進(jìn)入到“配置”界面。
此項(xiàng)是可選的,指定安裝Jenkins的HTTP地址。這個(gè)值用來(lái)在郵件中生產(chǎn)Jenkins鏈接。此項(xiàng)是有必要的,因?yàn)镴enkins無(wú)法探測(cè)到自己的URL地址。
配置SonarQube所在服務(wù)器的信息,建立Jenkins和SonarQube之間的通信。
Name:自定義一個(gè)適合的名字;
Server URL:SonarQube所在服務(wù)器的URL(IP或域名加端口,端口號(hào)默認(rèn)為9000);
Server authentication token:這里填寫SonarQube服務(wù)器當(dāng)前用戶的令牌。
SonarQube令牌的生成方法:登陸SonarQube服務(wù)器,選擇“頭像”--->“我的賬號(hào)”--->“安全”--->在“生成令牌”文本框中輸入自定義的名稱,然后點(diǎn)擊“生成”按鈕。生成的令牌ID只會(huì)顯示一次,所以如果有需要,可以進(jìn)行備份
生成SonarQube當(dāng)前用戶的令牌ID后,回到Jenkins的系統(tǒng)配置界面,并定位到“SonarQube servers”模塊,點(diǎn)擊“Server authentication token”選項(xiàng)的“添加”按鈕,選擇“Jenkins”,進(jìn)入到“添加憑據(jù)”窗口。
類型:選擇Secret text;
Secret:填入SonarQube當(dāng)前用戶生成的令牌ID;
ID:自定義一個(gè)名稱。
填寫完畢后,點(diǎn)擊“添加”按鈕,然后在“Server authentication token”的下拉選框中選擇相應(yīng)的憑據(jù)即可。
配置將要構(gòu)建的代碼所在的GitLab服務(wù)器信息,建立Jenkins和GitLab服務(wù)器之間的通信。
Connection name:自定義一個(gè)名稱;
Gitlab host URL:GItLab所在服務(wù)器的HTTP地址;
Credentials:添加GitLab API token,該token由GItLab生成。
GitLab API token的生成方法:進(jìn)入GitLab主頁(yè),點(diǎn)擊頁(yè)面右上角的頭像,在出現(xiàn)的懸框中點(diǎn)擊“Settings”,進(jìn)入到設(shè)置界面。在設(shè)置界面左側(cè)的導(dǎo)航欄中點(diǎn)擊“Access Token”,進(jìn)入“Access Token”界面。
Name:自定義一個(gè)名稱;
Expires at:添加生成token的時(shí)間(非必填項(xiàng));
Scopes:勾選api復(fù)選框;
Create personal access token:點(diǎn)擊此按鈕后會(huì)生成一個(gè)token,且生成的token會(huì)展示在“Active Personal Access Tokens”列表中。
生成GitLab API token后,回到Jenkins的系統(tǒng)配置界面,并定位到GitLab模塊。點(diǎn)擊Credentials的“添加”按鈕,選擇“jenkins”,進(jìn)入到“添加憑據(jù)”窗口。
類型:選擇GitLab API token;
API token:填入在GitLab中生成的API token;
ID:自定義一個(gè)名稱(非必填項(xiàng))。
所需的信息配置完畢后,點(diǎn)擊“Test Connection”按鈕,測(cè)試Jenkins和GitLab之間的連接是否成功。
若要將構(gòu)建后生成的jar包(后端)或dist目錄文件(前端)推送到遠(yuǎn)程服務(wù)器中,需配置此模塊。在此我們選擇用戶名和密碼來(lái)連接遠(yuǎn)程服務(wù)器。
Name:自定義一個(gè)名稱。在Job中使用Publish over SSH插件時(shí),此名稱將出現(xiàn)在“SSH Server”中“Name”選項(xiàng)的下拉列表中;
Hostname:服務(wù)器的主機(jī)名或IP地址;
Username:服務(wù)器的用戶名;
Remote Directory:遠(yuǎn)程服務(wù)器上真實(shí)存在的目錄,而且“Username”指定的用戶要有訪問(wèn)此文件夾的權(quán)限,插件將把文件推送到此目錄下;
Use password authentication, or use a different key:勾選此選項(xiàng),并在“Passphrase / Password”中輸入與Username匹配的密碼。
配置完后點(diǎn)擊“Test Configuration”,測(cè)試是否可以連接成功。
在Jenkins的使用中郵件提醒是一個(gè)常用功能,Jenkins默認(rèn)安裝了 Mailer Plugin插件用于實(shí)現(xiàn)此功能,但 Mailer Plugin功能簡(jiǎn)單不能滿足一些復(fù)雜需求,如:自定義郵件標(biāo)題、內(nèi)容等。Extended E-mail Notification(ext mail)是一個(gè)功能更為齊全,使用也更為復(fù)雜的插件。下面對(duì)此插件的配置做簡(jiǎn)要的說(shuō)明。
SMTP Server:SMTP服務(wù)器的地址;
SMPT Port:SMTP的端口號(hào),默認(rèn)為25;
SMTP Username:即在Jenkins Location模塊中填寫的“系統(tǒng)管理員郵件地址”;
SMTP Password:“系統(tǒng)管理員郵件地址”所對(duì)應(yīng)的密碼;
Default user E-mail suffix:默認(rèn)的郵箱后綴;
Default Content Type:默認(rèn)的郵件內(nèi)容格式;
Default Recipients:默認(rèn)收件人的郵箱地址(可填寫多個(gè),中間用英文逗號(hào)隔開(kāi)即可);
Default Subject:郵件標(biāo)題。例如,$PROJECT_NAME - Build # $BUILD_NUMBER - $BUILD_STATUS!。其中,$PROJECT_NAME為構(gòu)建項(xiàng)目名稱,$BUILD_NUMBER為構(gòu)建編號(hào),$BUILD_STATUS為構(gòu)建狀態(tài);
Default Content:郵件內(nèi)容;
1 <!DOCTYPE html>
2 <html>
3 <head>
4 <meta charset="UTF-8">
5 <title>${ENV, var="JOB_NAME"}-第${BUILD_NUMBER}次構(gòu)建日志</title>
6 </head>
7
8 <body leftmargin="8" marginwidth="0" topmargin="8" marginheight="4"
9 offset="0">
10 <table width="95%" cellpadding="0" cellspacing="0"
11 style="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif">
12 <tr>
13 <td>(本郵件由Jenkins系統(tǒng)自動(dòng)發(fā)布,請(qǐng)勿回復(fù)!)</td>
14 </tr>
15 <tr>
16 <td><h2>
17 <font color="#0000FF">構(gòu)建結(jié)果 - ${BUILD_STATUS}</font>
18 </h2></td>
19 </tr>
20 <tr>
21 <td><br />
22 <b><font color="#0B610B">構(gòu)建信息</font></b>
23 <hr size="2" width="100%" align="center" /></td>
24 </tr>
25 <tr>
26 <td>
27 <ul>
28 <li>項(xiàng)目名稱: ${PROJECT_NAME}</li>
29 <li>構(gòu)建編號(hào): 第${BUILD_NUMBER}次構(gòu)建</li>
30 <li>構(gòu)建狀態(tài): ${BUILD_STATUS}</li>
31 <li>觸發(fā)原因: ${CAUSE}</li>
32 <li>構(gòu)建日志: <a href="${BUILD_URL}console">${BUILD_URL}console</a></li>
33 <li>構(gòu)建 Url : <a href="${BUILD_URL}">${BUILD_URL}</a></li>
34 <li>工作目錄 : <a href="${PROJECT_URL}ws">${PROJECT_URL}ws</a></li>
35 <li>項(xiàng)目 Url : <a href="${PROJECT_URL}">${PROJECT_URL}</a></li>
36 </ul>
37 </td>
38 </tr>
39 <tr>
40 <td><b><font color="#0B610B">Changes Since Last
41 Successful Build:</font></b>
42 <hr size="2" width="100%" align="center" /></td>
43 </tr>
44 <tr>
45 <td>
46 <ul>
47 <li>歷史變更記錄 : <a href="${PROJECT_URL}changes">${PROJECT_URL}changes</a></li>
48 </ul> ${CHANGES_SINCE_LAST_SUCCESS,reverse=true, format="Changes for Build #%n:<br />%c<br />",showPaths=true,changesFormat="<pre>[%a]<br />%m</pre>",pathFormat=" %p"}
49 </td>
50 </tr>
51 <tr>
52 <td><b>Failed Test Results</b>
53 <hr size="2" width="100%" align="center" /></td>
54 </tr>
55 <tr>
56 <td><pre style="font-size: 11pt; font-family: Tahoma, Arial, Helvetica, sans-serif">$FAILED_TESTS</pre>
57 <br /></td>
58 </tr>
59 <tr>
60 <td><b><font color="#0B610B">構(gòu)建日志 (最后 100行):</font></b>
61 <hr size="2" width="100%" align="center" /></td>
62 </tr>
63 <!-- <tr>
64 <td>Test Logs (if test has ran): <a
65 href="${PROJECT_URL}ws/TestResult/archive_logs/Log-Build-${BUILD_NUMBER}.zip">${PROJECT_URL}/ws/TestResult/archive_logs/Log-Build-${BUILD_NUMBER}.zip</a>
66 <br />
67 <br />
68 </td>
69 </tr> -->
70 <tr>
71 <td><textarea cols="80" rows="30" readonly="readonly"
72 style="font-family:Courier New">${BUILD_LOG, maxLines=100}
首先進(jìn)入Jenkins主界面,在面板左側(cè)的導(dǎo)航欄中點(diǎn)擊“新建任務(wù)”,進(jìn)入“新建任務(wù)”界面。
進(jìn)入“新建任務(wù)”界面后,在“任務(wù)名稱”文本框中輸入一個(gè)合法的名稱(該名稱最好能簡(jiǎn)短、清晰地描述所要構(gòu)建的項(xiàng)目,且不能與已有的任務(wù)名稱重合),然后選擇“構(gòu)建一個(gè)Maven項(xiàng)目”,點(diǎn)擊左下角的“確定”按鈕,進(jìn)入任務(wù)配置界面。
在“General”選項(xiàng)卡下勾選“丟棄舊的構(gòu)建”,填寫需要保留的構(gòu)建天數(shù)和構(gòu)建的最大個(gè)數(shù)。若不及時(shí)清理舊的構(gòu)建,則會(huì)消耗服務(wù)器的磁盤空間。
在“源碼管理”模塊中選擇Git。無(wú)論是GitHub還是私有的GitLab,一般都支持兩種模式:SSH模式和HTTP模式。
Repository URL:要構(gòu)建的項(xiàng)目在GitLab中的HTTP地址。首先進(jìn)入到所要構(gòu)建的項(xiàng)目在GitLab中的主界面,在項(xiàng)目的URL下拉選框中選擇“HTTP”,并點(diǎn)擊右側(cè)的“復(fù)制”按鈕,將復(fù)制的HTTP地址粘貼到“Repository URL”文本框中即可。
Credentials:點(diǎn)擊右側(cè)的“添加”按鈕,選擇“Jenkins”選項(xiàng)后會(huì)彈出一個(gè)“添加憑據(jù)”彈窗。
添加憑據(jù)時(shí),類型選擇“Username with password”,然后在“用戶名”文本框中輸入GitLab的登陸賬戶,“密碼”文本框中輸入與賬戶相匹配的密碼,“ID”文本框中填入自定義的名稱,但不能與已有的憑據(jù)ID重合。填寫完畢后,點(diǎn)擊“添加”按鈕,所添加的憑據(jù)就會(huì)出現(xiàn)在“Credentials”的下拉選框中,在選框中選擇相應(yīng)的憑據(jù)即可。
首先登陸Jenkins所在的master服務(wù)器,檢查在~/.ssh目錄下是否有已生成的公鑰和私鑰。其中,公鑰的文件名為id_rsa.pub,私鑰的文件名為id_rsa。若公鑰和私鑰都存在,則將公鑰拷貝到GitLab中,私鑰拷貝到Jenkins中。
1)將公鑰拷貝到GitLab
首先登陸到GitLab中,點(diǎn)擊頁(yè)面右上角的頭像,選擇Settings-->SSH Keys,進(jìn)入到“SSH Keys”界面。
Key:將Jenkins所在master服務(wù)器上的公鑰(id_rsa.pub)拷貝到此文本框中;
Title:填寫一個(gè)適合的名稱;
Add key:點(diǎn)擊此按鈕將公鑰添加到GitLab中;
Your SSH keys:添加到GitLab的公鑰會(huì)顯示在此列表中。
2)添加Jenkins全局憑據(jù)
首先登陸到Jenkins中,選擇系統(tǒng)管理-->Manager Credentials-->全局憑據(jù)-->添加憑據(jù),進(jìn)入到“添加憑據(jù)”界面。
類型:選擇“SSH Username with private key”;
ID:填寫一個(gè)獨(dú)一無(wú)二的名稱;
描述:簡(jiǎn)短、清晰的描述此憑據(jù)的作用;
Username:填寫Master服務(wù)器的用戶名,如root;
Private Key:將Master服務(wù)器上的私鑰(id_rsa)拷貝到此文本框中。
設(shè)置好全局憑據(jù)后,將GitLab中項(xiàng)目的SSH地址復(fù)制到Jenkins中相應(yīng)job配置頁(yè)面的“源碼管理”模塊中。在“Credentials”中選擇相應(yīng)的全局憑據(jù)。
Branches to build:要構(gòu)建的代碼在Git倉(cāng)庫(kù)中的分支名。由于我們要將dev分支(開(kāi)發(fā)分支代碼,具體名稱視Gitlab中的情況而定)的代碼merge到test分支(測(cè)試分支代碼,具體名稱視Gitlab中的情況而定)上,所以此處填寫dev。若不需要在構(gòu)建前執(zhí)行merge操作,則此處填寫實(shí)際要構(gòu)建的代碼分支名稱即可。
1)Merge before build
由于我們要在構(gòu)建前將dev分支的代碼merge到test分支上,因此要在“Additional Behaviours”中新增一個(gè)“Merge before build”模塊。若不需要在構(gòu)建前執(zhí)行merge操作,則可省略此步驟。
Name of repository:遠(yuǎn)程代碼倉(cāng)庫(kù)的名稱,即所要構(gòu)建的代碼分支所在的倉(cāng)庫(kù),默認(rèn)填寫origin即可;
Branch to merge to:代碼將要merge到的分支。由于我們要將dev分支的代碼merge到test分支,因此該處填寫test;
Merge strategy:默認(rèn)選擇default即可;
Fast-forward mode:默認(rèn)選擇--ff即可。
2)Custom user name/e-mail address
當(dāng)在任務(wù)中配置了“Merge before build”或向遠(yuǎn)程Git倉(cāng)庫(kù)中push版本標(biāo)簽時(shí),會(huì)出現(xiàn)無(wú)法識(shí)別用戶的情況,如下圖所示:
要解決這個(gè)問(wèn)題,需要在“Additional Behaviours”的“新增”下拉選框中選擇“Custom user name/e-mail address”選項(xiàng),添加Gitlab用戶名和對(duì)應(yīng)的電子郵箱。
查看Gitlab用戶名和電子郵箱的方法:進(jìn)入到Gitlab主頁(yè),點(diǎn)擊右上角的頭像,在出現(xiàn)的下拉選框中選擇“Settings”進(jìn)入到設(shè)置界面。在設(shè)置界面中即可看到用戶名和對(duì)應(yīng)的郵箱。然后將用戶名和郵箱粘貼到“Custom user name/e-mail address”中相應(yīng)的文本框中即可。
若不需要自動(dòng)觸發(fā)項(xiàng)目進(jìn)行構(gòu)建,可忽略此步驟。
定位到 “構(gòu)建觸發(fā)器”模塊,勾選“Build when a change is pushed to GitLab.”,并記下這一選項(xiàng)末尾的“GitLab webhook URL”。
此外,還要點(diǎn)擊該選項(xiàng)中的“高級(jí)”按鈕,隨后點(diǎn)擊“Secret token”項(xiàng)的 “Generate” ,生成 Secret token。保存這里生成的 Secret token,它將用于后面 GitLab 的配置。
下面對(duì)各項(xiàng)進(jìn)行簡(jiǎn)要介紹:
1)Enabled GitLab triggers
Push Events:當(dāng)有代碼Push到Git倉(cāng)庫(kù)時(shí),自動(dòng)觸發(fā)Jenkins構(gòu)建;
Opened Merge Request Events:當(dāng)在Git中新建一個(gè)Merge請(qǐng)求時(shí),自動(dòng)觸發(fā)Jenkins構(gòu)建;
Accepted Merge Request Events:當(dāng)在GitLab中建立的Merge請(qǐng)求被接受后,自動(dòng)觸發(fā)Jenkins構(gòu)建。例如,在GItLab中,當(dāng)dev01分支的代碼請(qǐng)求merge到dev分支時(shí),若此請(qǐng)求被成功處理,就會(huì)觸發(fā)Jenkins自動(dòng)構(gòu)建,Jenkins會(huì)將dev分支的代碼merge到test分支;
Closed Merge Request Events:當(dāng)在GitLab中建立的Merge請(qǐng)求被關(guān)閉時(shí),自動(dòng)觸發(fā)Jenkins構(gòu)建。
2)保持默認(rèn)選項(xiàng)
3)Allowed branches
此項(xiàng)用于篩選可以觸發(fā)任務(wù)自動(dòng)構(gòu)建的代碼分支。勾選“Filter branches by name”,在“inclued”文本框中填寫允許自動(dòng)觸發(fā)任務(wù)構(gòu)建的代碼分支名稱,名稱之間用英文逗號(hào)分隔。
配置GitLab:此處以merge觸發(fā)為例,即當(dāng)Git倉(cāng)庫(kù)中發(fā)生Merge事件時(shí),觸發(fā)Jenkins自動(dòng)構(gòu)建。打開(kāi)GItLab,進(jìn)入到相應(yīng)的項(xiàng)目頁(yè)面中,在頁(yè)面左側(cè)的導(dǎo)航欄中選擇Settings--->Integrations,進(jìn)入到“Integrations Settings”界面。在該界面中,在“URL”文本框中輸入“GitLab webhook URL”尾部的HTTP地址;在“Secret Token”中輸入在Jenkins中生成的Secret token;在“Trigger”中勾選“Merge Request events”,然后點(diǎn)擊“Add Webhook”按鈕。
點(diǎn)擊“Add webhook”按鈕后,添加的webhook會(huì)出現(xiàn)在“webhooks”列表中。在列表中選擇新添加的webhook,在其右邊的“Test”下拉列表中選擇相應(yīng)的Trigger(即Merge requests events),點(diǎn)擊后在頁(yè)面上方如果出現(xiàn)“Hook executed successfully:HTTP 200”的提示,則表明配置成功。
在GitLab中建立Merge請(qǐng)求。首先,登陸GitLab服務(wù)器,選擇相應(yīng)的項(xiàng)目并進(jìn)入到該項(xiàng)目頁(yè)面,在頁(yè)面左側(cè)的導(dǎo)航欄中選擇“Merge Requests”,進(jìn)入到“Merge Requests”界面。在該界面的右上角點(diǎn)擊“New Merge Request”,新建一個(gè)Merge請(qǐng)求。
在Merge請(qǐng)求頁(yè)面中,選擇相應(yīng)的源項(xiàng)目、目標(biāo)項(xiàng)目,以及源分支和目標(biāo)分支。
點(diǎn)擊“Compare branches and continue”,會(huì)進(jìn)入到下一個(gè)頁(yè)面,在此頁(yè)面中可以填寫更為詳細(xì)的merge requests信息。
點(diǎn)擊“Submit合并請(qǐng)求”按鈕,進(jìn)入下一個(gè)頁(yè)面,在該頁(yè)面中可以編輯或關(guān)閉此次merge請(qǐng)求。
當(dāng)所指定的源分支中的代碼發(fā)生更改后(即執(zhí)行了git commit命令),在此頁(yè)面中會(huì)出現(xiàn)一個(gè)“Merge”按鈕。點(diǎn)擊此按鈕后,源分支上的代碼就會(huì)被merge到目標(biāo)分支上。同時(shí),會(huì)觸發(fā)Jenkins自動(dòng)執(zhí)行構(gòu)建任務(wù),將dev分支上的代碼merge到test分支上。
定時(shí)構(gòu)建的選項(xiàng)包括“輪詢SCM”和“定時(shí)構(gòu)建”。定時(shí)構(gòu)建適用于每日構(gòu)建或每周構(gòu)建的任務(wù),可以通過(guò)設(shè)定具體的時(shí)間點(diǎn)和時(shí)間段來(lái)執(zhí)行指定的任務(wù)。構(gòu)建任務(wù)的內(nèi)容填寫在“日程表”文本框中,而且填寫完畢后下方還會(huì)提示上次運(yùn)行和下次運(yùn)行的時(shí)間點(diǎn),用于驗(yàn)證配置是否正確。
定時(shí)構(gòu)建的語(yǔ)法是* * * * *。
當(dāng)所要構(gòu)建的兩個(gè)或多個(gè)項(xiàng)目之間存在關(guān)聯(lián)時(shí),可以勾選此選項(xiàng)。在“關(guān)注的項(xiàng)目”文本框中可以填寫多個(gè)已存在的項(xiàng)目,項(xiàng)目之間用英文的逗號(hào)分隔。例如,任務(wù)B要在任務(wù)A構(gòu)建成功后自動(dòng)構(gòu)建,可在“關(guān)注的項(xiàng)目”文本框中填寫A,同時(shí)選擇“只有構(gòu)建穩(wěn)定時(shí)觸發(fā)”,即只有項(xiàng)目A成功構(gòu)建才會(huì)自動(dòng)觸發(fā)B構(gòu)建。
若要在構(gòu)建前清理工作空間,以免工作空間中的內(nèi)容對(duì)本次構(gòu)建產(chǎn)生影響和及時(shí)清理磁盤空間,可勾選“Delete workspace before build starts”選項(xiàng)。
Jenkins默認(rèn)的構(gòu)建版本號(hào)只是簡(jiǎn)單的構(gòu)建總次數(shù),不包含有年月日及當(dāng)日構(gòu)建次數(shù)等信息,可勾選“Create a formatted version number”選項(xiàng)自定義所需要的構(gòu)建版本號(hào)。
Environment Variable Name:填寫一個(gè)合適的名稱,此名稱可作為全局環(huán)境變量被引用;
Version Number Format String:填寫自定義的格式化構(gòu)建版本號(hào),如${JOB_NAME}_${BUILD_DATE_FORMATTED, "yyyyMMdd"}_${BUILDS_TODAY},其中,${JOB_NAME}為項(xiàng)目名稱,${BUILD_DATE_FORMATTED, "yyyyMMdd"}為格式化后的日期,${BUILDS_TODAY}為今日構(gòu)建次數(shù);
Skip Builds worse than:當(dāng)本次構(gòu)建任務(wù)的狀態(tài)比此處所選的還要糟糕時(shí),則本次構(gòu)建不計(jì)入構(gòu)建總次數(shù)。例如,此處選擇“SUCCESS”,但本次任務(wù)的構(gòu)建狀態(tài)為“FAILURE”,則本次構(gòu)建不計(jì)入今日(或周、月、年)構(gòu)建總次數(shù);
Build Display Name:當(dāng)勾選“Use the formatted version number for build display name”時(shí),自定義的構(gòu)建版本號(hào)會(huì)替代原來(lái)的“#XXX”顯示在任務(wù)欄中,如下圖所示。
其他選項(xiàng)保持默認(rèn)即可。
若構(gòu)建前要利用Sonar Scanner對(duì)代碼執(zhí)行靜態(tài)質(zhì)量掃描操作,則需要在“Add pre-build step”下拉選框中選擇“Execute SonarQube Scanner”選項(xiàng)。
下面對(duì) “Execute SonarQube Scanner”各項(xiàng)做簡(jiǎn)要的介紹:
Task to run:自定義一個(gè)名稱(非必填項(xiàng));
JDK:在 JDK 選擇框中選擇 SonarQube Scanner 使用的 JDK(注意這里必須是 JDK 不能是 JRE);
Path to project properties:非必填項(xiàng)。這里可以指定一個(gè) sonar-project.properties 文件,如果不指定的話會(huì)使用項(xiàng)目默認(rèn)的 properties 文件;
Analysis properties:這里需要輸入一些配置參數(shù)用來(lái)傳遞給 SonarQube,這里的參數(shù)優(yōu)先級(jí)高于sonar-project.properties文件里面的參數(shù),所以可以在這里來(lái)配置所有的參數(shù)以替代 sonar-project.properties 文件。下面介紹一些常用的參數(shù):
Additional arguments:非必填項(xiàng)。此輸入框中可以輸入一些附加的參數(shù),示例中的-X意思是進(jìn)入SonarQube Scanner的Debug模式,這樣會(huì)輸出更多的日志信息;
JVM Options:非必填項(xiàng)。可以輸入在執(zhí)行 SonarQube Scanner 時(shí)需要的JVM參數(shù)。
projectKey和projectName的生成方法:生成sonar.projectKey和sonar.projectName時(shí)需要登陸SonarQube界面。在SonarQube界面中新建一個(gè)項(xiàng)目時(shí),會(huì)要求輸入“項(xiàng)目標(biāo)識(shí)”和“顯示名”,“項(xiàng)目標(biāo)識(shí)”即“sonar.projectKey”,“顯示名”即“sonar.projectName”。
在SonarQube界面中新建項(xiàng)目的步驟:
Root POM:最上層pom.xml文件的路徑,這里是相對(duì)于${WORKSPACE}的路徑。如果不做設(shè)置,默認(rèn)是在工作目錄的根目錄下,填寫pom.xml即可。如果不是默認(rèn)路徑,例如,在${WORKSPACE}/my-project/pom.xml下,這里寫上/my-project/pom.xml。
Goals and options:這里就是mvn指令后面的部分,如clean package,也可以帶參數(shù)。比如,要跳過(guò)單元測(cè)試,就使用-Dmaven.test.skip=true。
在“構(gòu)建后操作步驟”中添加“Git Publisher”和“Send build artifacts over SSH”。其中,“Git Publisher”的作用是將在Jenkins中merge后的代碼push到遠(yuǎn)程倉(cāng)庫(kù)中相應(yīng)的分支。“Send build artifacts over SSH”的作用是將編譯打包后的文件(如war包、jar包)推送到遠(yuǎn)程服務(wù)器。
Branch to push:代碼merge成功后要push到的分支的名稱。在我們的示例中,Jenkins在執(zhí)行構(gòu)建任務(wù)時(shí),將dev分支上的代碼merge到了test分支上。merge成功后,還需要將合并后的代碼push到遠(yuǎn)程倉(cāng)庫(kù)中指定的分支上。此處我們將合并后的代碼push到了test分支上;
Target remote name:遠(yuǎn)程代碼倉(cāng)庫(kù)的名稱,即上面所填寫的代碼分支所在的Git倉(cāng)庫(kù)。
Tags:在將merge后的代碼push到遠(yuǎn)程倉(cāng)庫(kù)中指定的分支時(shí),還可以為此次提交的代碼打上一個(gè)tag,此tag也會(huì)同時(shí)被push到遠(yuǎn)程倉(cāng)庫(kù)中。點(diǎn)擊“Add Tags”按鈕,填寫相應(yīng)的配置信息。
在這個(gè)模塊中配置相應(yīng)的信息,將構(gòu)建后編譯生成的jar包推送到遠(yuǎn)程服務(wù)器上指定的目錄。也可編寫shell腳本,對(duì)應(yīng)用進(jìn)行部署。
Name:選擇在Jenkins“系統(tǒng)管理--->系統(tǒng)設(shè)置”中設(shè)置的SSH Server的名字;
Source files:拷貝到遠(yuǎn)程服務(wù)器上的文件。需要上傳的文件必須位于當(dāng)前的workspace中,否則會(huì)上傳失敗。如果只執(zhí)行命令而不需要傳輸文件時(shí),此處可為空;
Remove prefix:在“Source files”配置的路徑中要移除的前綴。在Source files文本框中填入的地址,會(huì)默認(rèn)在服務(wù)器下創(chuàng)建相同的目錄,所以要將我們不需要的前綴在這里剔除掉,只傳輸XXX.jar;
Remote directory:遠(yuǎn)程服務(wù)器接收文件的目錄,此目錄是相對(duì)于“SSH Server”中的“Remote directory”的,如果不存在將會(huì)自動(dòng)創(chuàng)建;
Exec command:文件傳輸任務(wù)執(zhí)行完畢后,在遠(yuǎn)程服務(wù)器上執(zhí)行的腳本(可填寫腳本所在目錄)。
Exec command中的腳本:
1 #! /bin/bash
2 #!/bin/bash
3 export PROJECT_HOME="/opt/opanalysis"
4 export JAR_HOME="$PROJECT_HOME/new-jar"
5 export BACKUP_HOME="$PROJECT_HOME/backup-jar"
6 export ANALYSIS=op-analysis.jar
7 export TEAMBITION=op-teambition.jar
8 export CAS=op-cas.jar
9 export GATEWAY=op-gateway.jar
10 export LOG_HOME="/opt/opanalysis/logs"
11 export ANALYSIS_log="$LOG_HOME/op-analysis.log"
12 export TEAMBITION_log="$LOG_HOME/op-teambition.log"
13 export CAS_log="$LOG_HOME/op-cas.log"
14 export GATEWAY_log="$LOG_HOME/op-gateway.log"
15 BACKUP_FILE=v${BUILD_VERSION}_$(date +%Y-%m-%d_%H:%M:%S)
16 echo "****** Backup old jar ******"
17 mkdir $BACKUP_HOME/$BACKUP_FILE
18 cp $JAR_HOME/*.jar $BACKUP_HOME/$BACKUP_FILE
19 echo "****** Remove old jar ******"
20 find $JAR_HOME -type f -name "*.jar" -print0 | xargs -0 rm -rf
21 echo "****** Copy new jar ******"
22 cp $PROJECT_HOME/op-analysis/target/$ANALYSIS $JAR_HOME
23 cp $PROJECT_HOME/op-teambition/target/$TEAMBITION $JAR_HOME
24 cp $PROJECT_HOME/op-cas/target/$CAS $JAR_HOME
25 cp $PROJECT_HOME/op-gateway/target/$GATEWAY $JAR_HOME
26 if [ -e $JAR_HOME/$ANALYSIS -a -e $JAR_HOME/$TEAMBITION -a -e $JAR_HOME/$CAS -a -e $JAR_HOME/$GATEWAY ]; then
27 echo "The new jars were successfully replicated"
28 else
29 echo "The new jars replication failed"
30 exit 1
31 fi
32 echo "****** Stop the old processes ******"
33 P_ID=$(ps -ef | grep -w $ANALYSIS | grep -v "grep" | awk '{print $2}')
34 if [ "$P_ID" == "" ]; then
35 echo "$ANALYSIS process does not exist or has stopped successfully"
36 else
37 kill -9 $P_ID
38 echo "$ANALYSIS was successfully killed"
39 fi
40 P_ID=$(ps -ef | grep -w $TEAMBITION | grep -v "grep" | awk '{print $2}')
41 if [ "$P_ID" == "" ]; then
42 echo "$TEAMBITION process does not exist or has stopped successfully"
43 else
44 kill -9 $P_ID
45 echo "$TEAMBITION was successfully killed"
46 fi
47 P_ID=$(ps -ef | grep -w $CAS | grep -v "grep" | awk '{print $2}')
48 if [ "$P_ID" == "" ]; then
49 echo "$CAS process does not exist or has stopped successfully"
50 else
51 kill -9 $P_ID
52 echo "$CAS was successfully killed"
53 fi
54 P_ID=$(ps -ef | grep -w $GATEWAY | grep -v "grep" | awk '{print $2}')
55 if [ "$P_ID" == "" ]; then
56 echo "$GATEWAY process does not exist or has stopped successfully"
57 else
58 kill -9 $P_ID
59 echo "$GATEWAY was successfully killed"
60 fi
61 echo "****** Old processes stop success ******"
62 echo "****** Start op-analysis.jar... ******"
63 nohup java -jar $JAR_HOME/$ANALYSIS > $ANALYSIS_log 2>&1 &
64 EXEXUTE_STATUS_ANALYSIS=$?
65 sleep 10
66 if [ $EXEXUTE_STATUS_ANALYSIS -eq 0 -a $(ps -ef | grep -w $ANALYSIS | grep -v "grep" | wc -l) -ne 0 ]; then
67 echo "$ANALYSIS started successfully"
68 else
69 echo "$ANALYSIS failed to start"
70 fi
71 echo "****** Start op-teambition.jar... ******"
72 nohup java -jar $JAR_HOME/$TEAMBITION > $TEAMBITION_log 2>&1 &
73 EXECUTE_STATUS_TEAMBITION=$?
74 sleep 10
75 if [ $EXECUTE_STATUS_TEAMBITION -eq 0 -a $(ps -ef | grep -w $TEAMBITION | grep -v "grep" | wc -l) -ne 0 ]; then
76 echo "$TEAMBITION started successfully"
77 else
78 echo "$TEAMBITION failed to start"
79 fi
80 echo "****** Start op-cas.jar... ******"
81 nohup java -jar $JAR_HOME/$CAS > $CAS_log 2>&1 &
82 EXECUTE_STATUS_CAS=$?
83 sleep 10
84 if [ $EXECUTE_STATUS_CAS -eq 0 -a $(ps -ef | grep -w $CAS | grep -v "grep" | wc -l) -ne 0 ]; then
85 echo "$CAS started successfully"
86 else
87 echo "$CAS failed to start"
88 fi
89 echo "****** Start op-gateway.jar... ******"
90 nohup java -jar $JAR_HOME/$GATEWAY > $GATEWAY_log 2>&1 &
91 EXECUTE_STATUS_GATEWAY=$?
92 sleep 10
93 if [ $EXECUTE_STATUS_GATEWAY -eq 0 -a $(ps -ef | grep -w $GATEWAY | grep -v "grep" | wc -l) -ne 0 ]; then
94 echo "$GATEWAY started successfully"
95 else
96 echo "$GATEWAY failed to start"
97 fi
98 echo "****** Over ******"
在“增加構(gòu)建后操作步驟”下拉選框中選擇“Editable Email Notification”,選擇后會(huì)在“構(gòu)建后操作”中出現(xiàn)“Editable Email Notification”模塊。
Jenkins支持Master/Slave這種分布式運(yùn)行模式。將安裝Jenkins的機(jī)器作為Master節(jié)點(diǎn),然后用戶通過(guò)界面配置來(lái)添加Slave節(jié)點(diǎn)。在用戶配置具體任務(wù)的時(shí)候可以選擇Master機(jī)器本身或者某個(gè)Slave節(jié)點(diǎn)來(lái)運(yùn)行。Jenkins在實(shí)際運(yùn)行任務(wù)的時(shí)候,將作業(yè)分布到指定的Master或Slave節(jié)點(diǎn)上,使得單個(gè)節(jié)點(diǎn)安裝的Jenkins服務(wù)器能夠管理多個(gè)節(jié)點(diǎn),運(yùn)行大批量的任務(wù),以及為它們提供不同的系統(tǒng)環(huán)境和配置。
創(chuàng)建和配置Jenkins Slave節(jié)點(diǎn)。選擇 系統(tǒng)管理-->節(jié)點(diǎn)管理--->新建節(jié)點(diǎn) 選項(xiàng),可以創(chuàng)建全新的Slave節(jié)點(diǎn),也可以從已有的Jenkins節(jié)點(diǎn)復(fù)制。
名稱:節(jié)點(diǎn)獨(dú)一無(wú)二的名稱,自行命名;
描述:節(jié)點(diǎn)的描述;
執(zhí)行器數(shù)量:在該節(jié)點(diǎn)可以并行運(yùn)行的最大任務(wù)數(shù)量,建議和CPU的內(nèi)核數(shù)相等,這里設(shè)置的值太高會(huì)導(dǎo)致節(jié)點(diǎn)負(fù)荷過(guò)大,在運(yùn)行多個(gè)任務(wù)時(shí),任務(wù)執(zhí)行耗時(shí)過(guò)長(zhǎng);
遠(yuǎn)程工作目錄:指定Slave節(jié)點(diǎn)的workspace目錄,但是一些重要的數(shù)據(jù)會(huì)保存在Master節(jié)點(diǎn)上,一些源碼和文件會(huì)直接放置在運(yùn)行的Slave節(jié)點(diǎn)上,因此這里需要指定一個(gè)目錄;
標(biāo)簽:用來(lái)表示節(jié)點(diǎn)的群組。例如,如果節(jié)點(diǎn)都是Windows系統(tǒng)的節(jié)點(diǎn),可以提供“Windows Node”作為標(biāo)簽,在配置任務(wù)時(shí)可以不用指定具體的節(jié)點(diǎn),而指定對(duì)應(yīng)的群組;
用法:節(jié)點(diǎn)有兩種使用模式。默認(rèn)是Use this node as much as possible。在這種模式下,如果任務(wù)沒(méi)有指定具體的運(yùn)行節(jié)點(diǎn),那么會(huì)隨機(jī)指派一個(gè)可用節(jié)點(diǎn)。當(dāng)節(jié)點(diǎn)配置為這種模式時(shí),在需要的時(shí)候可以被Jenkins隨機(jī)調(diào)用。還有一種模式是Only build jobs with label expressions matching this node。在這種模式下,只有當(dāng)任務(wù)指定使用該節(jié)點(diǎn)時(shí),才會(huì)使用該節(jié)點(diǎn),可以用于資源受嚴(yán)格控制的場(chǎng)景及專門用于某些任務(wù)。
這里主要介紹Launch slave agents via SSH連接方式(配置節(jié)點(diǎn)前必須安裝SSH Agent Plugin插件,否則不能出現(xiàn)Launch slave agents via SSH選項(xiàng))。
啟動(dòng)方式:選擇Launch slave agents via SSH;
主機(jī):填寫Slave機(jī)器的IP地址;
Credentials:添加憑證信息
類型:選擇SSH Username with private key;
ID:填寫一個(gè)獨(dú)一無(wú)二的ID名;
描述:填寫能清楚描述此憑證的信息;
Username:填寫Master節(jié)點(diǎn)所在服務(wù)器的用戶名;
Private Key:填寫Master節(jié)點(diǎn)所在服務(wù)器的私鑰。
在配置Slave節(jié)點(diǎn)信息之前,需要將Master節(jié)點(diǎn)服務(wù)器上的公鑰推送到Slave節(jié)點(diǎn)服務(wù)器上:
1 # 生成公鑰和私鑰
2 ssh-keygen -t rsa
3 # 進(jìn)入到公鑰和私鑰所在的目錄
4 cd ~/.ssh
5 # 查看生成的公鑰
6 cat id_rsa.pub
7 # 查看生成的私鑰
8 cat id_rsa
9 # 將公鑰推送到Slave節(jié)點(diǎn)服務(wù)器上
10 ssh-copy-id -i ~/.ssh/id_rsa.pub root@172.16.239.51
若沒(méi)有登陸Master節(jié)點(diǎn)服務(wù)器的權(quán)限,可以在Slave節(jié)點(diǎn)所在服務(wù)器的~/.ssh目錄下新建一個(gè)authorized_keys的文件,并將Master節(jié)點(diǎn)服務(wù)器的公鑰粘貼在此文件中。
在系統(tǒng)的全局配置中,我們會(huì)設(shè)定一些工具的執(zhí)行路徑。如果在Slave節(jié)點(diǎn)上工具的執(zhí)行路徑與全局配置不同,就需要重新選擇工具名稱,給予新的路徑,覆蓋全局配置中的默認(rèn)路徑。建議在系統(tǒng)的全局工具配置中已有的工具都要在Slave節(jié)點(diǎn)所在的服務(wù)器上安裝,否則構(gòu)建任務(wù)的時(shí)候會(huì)出錯(cuò)。
選擇一個(gè)要在Slave節(jié)點(diǎn)上運(yùn)行的任務(wù),進(jìn)入到其設(shè)置界面,定位到界面中的General模塊,勾選“限制項(xiàng)目的運(yùn)行節(jié)點(diǎn)”,在出現(xiàn)的文本框中輸入Slave節(jié)點(diǎn)的名稱,應(yīng)用并保存該配置,當(dāng)構(gòu)建該任務(wù)時(shí),會(huì)自動(dòng)在該Slave節(jié)點(diǎn)上運(yùn)行。
(1)無(wú)法從遠(yuǎn)程Git倉(cāng)庫(kù)中拉取代碼
需要將GitLab所在服務(wù)器的IP地址和對(duì)應(yīng)的域名添加到Slave服務(wù)器的hosts文件中:
# 編輯hosts文件
vim /etc/hosts
(2)無(wú)法將Sonar Scanner的代碼掃描結(jié)果發(fā)送到Sonar Qube上進(jìn)行展示
需要將Sonar Qube的用戶名和對(duì)應(yīng)的登陸密碼添加到Analysis properties中:
(3)無(wú)法找到Maven的配置文件
在slave服務(wù)器中,maven的配置文件(settings.xml)的路徑需要和master服務(wù)器上的路徑一致,否則構(gòu)建時(shí)會(huì)出錯(cuò)。
在對(duì)前端項(xiàng)目進(jìn)行構(gòu)建之前,需要在Jenkins的Master服務(wù)器上安裝NodeJs、在Jenkins上安裝NodeJS插件。此外還要在測(cè)試服務(wù)器上安裝Nginx。
進(jìn)入到測(cè)試服務(wù)器,在nginx的安裝目錄下找到nginx.conf文件,并使用vim命令對(duì)該文件進(jìn)行編輯。
首先進(jìn)入Jenkins主界面,在面板左側(cè)的導(dǎo)航欄中點(diǎn)擊“新建任務(wù)”,進(jìn)入“新建任務(wù)”界面。
進(jìn)入“新建任務(wù)”界面后,在“任務(wù)名稱”文本框中輸入一個(gè)合法的名稱(該名稱最好能簡(jiǎn)短、清晰地描述所要構(gòu)建的項(xiàng)目,且不能與已有的任務(wù)名稱重合),然后選擇“構(gòu)建一個(gè)自由風(fēng)格的軟件項(xiàng)目”,點(diǎn)擊左下角的“確定”按鈕,進(jìn)入任務(wù)配置界面。
請(qǐng)參考5.2節(jié)
請(qǐng)參考5.3節(jié)
請(qǐng)參考5.4節(jié)
前端代碼在構(gòu)建時(shí)需要NodeJS進(jìn)行編譯、打包,所以要在“構(gòu)建環(huán)境”中配置NodeJS環(huán)境。安裝NodeJS插件后,會(huì)在“構(gòu)建環(huán)境”模塊中出現(xiàn)“Provide Node & npm bin/ folder to PATH“選項(xiàng),勾選此選項(xiàng)。
NodeJS Installation:在“全局工具配置”界面中指定NodeJS安裝路徑時(shí)所填寫的名稱會(huì)出現(xiàn)在此下拉列表中,在列表中選擇所需的名稱即可;
npmrc file:選擇“- use system default –”;
Cache location:選擇“Default (~/.npm or %APP_DATA%\npm-cache)”。
“構(gòu)建環(huán)境”模塊中的其他選項(xiàng)配置請(qǐng)參考5.5節(jié)。
在“構(gòu)建”模塊的“增加構(gòu)建步驟”下拉選框中選擇“執(zhí)行shell”選項(xiàng),然后在“執(zhí)行shell”的“命令”文本框中輸入編譯、打包前端代碼的命令。
命令如下:
1 #!/bin/bash
2 export WORKSPACE_HOME="/var/lib/jenkins/workspace/operation-analysis-front"
3 # 進(jìn)入項(xiàng)目的工作空間
4 cd $WORKSPACE_HOME
5 # 執(zhí)行npm install后,npm會(huì)根據(jù)在package.json中對(duì)各種依賴的定義去安裝這些依賴
6 npm install
7 # 打包項(xiàng)目代碼。打包完成后會(huì)生成一個(gè)dist目錄,所要部署的文件就存放在dist目錄下
8 npm run test
9 # 進(jìn)入到dist目錄
10 cd $WORKSPACE_HOME/dist
11 # 刪除舊的壓縮文件
12 rm -f dist.tar.gz
13 # 對(duì)新的部署文件進(jìn)行打包壓縮
14 tar -zcvf dist.tar.gz *
請(qǐng)參考5.6節(jié)。不同的是前端代碼的掃描對(duì)象為JavaScript,因此代碼語(yǔ)言要設(shè)置成js,即sonar.language=js。
請(qǐng)參考5.8.1節(jié)
在這個(gè)模塊中配置相應(yīng)的信息,將構(gòu)建后編譯生成的dist目錄下的部署文件推送到遠(yuǎn)程服務(wù)器上指定的目錄。
Name:選擇在Jenkins“系統(tǒng)管理--->系統(tǒng)設(shè)置”中設(shè)置的SSH Server的名字;
Source files:拷貝到遠(yuǎn)程服務(wù)器上的文件。需要上傳的文件必須位于當(dāng)前的workspace中,否則會(huì)上傳失敗。可填寫相對(duì)于workspace的路徑名。例如,由于我們將dist目錄下的文件打包成了一個(gè)壓縮包,所以此處填寫dist/dist.tar.gz即可;
Remove prefix:在“Source files”配置的路徑中要移除的前綴。在Source files文本框中填入的地址,會(huì)默認(rèn)在服務(wù)器中創(chuàng)建相同的目錄,所以要將我們不需要的前綴在這里剔除掉,例如,去掉dist;
Remote directory:遠(yuǎn)程服務(wù)器接收文件的目錄,此目錄是相對(duì)于“SSH Server”中的“Remote directory”的,如果不存在將會(huì)自動(dòng)創(chuàng)建;
Exec command:文件傳輸任務(wù)執(zhí)行完畢后,在遠(yuǎn)程服務(wù)器上執(zhí)行的腳本(可填寫腳本所在目錄)。
Exec command中的腳本如下:
1 #!/bin/bash
2 export PROJECT_HOME="/usr/local/operation_analysis/op-web-package"
3 export DIST_HOME="$PROJECT_HOME/dist"
4 export BACKUP_HOME="$PROJECT_HOME/backup-dist"
5 export TARGET_HOME="/opt/opanalysis-front"
6 BACKUP_FILE="v${BUILD_VERSION}_$(date +%Y-%m-%d_%H:%M:%S)"
7 echo "****** Backup old dist ******"
8 mkdir $BACKUP_HOME/$BACKUP_FILE
9 cp -r $DIST_HOME $BACKUP_HOME/$BACKUP_FILE
10 echo "****** Remove old dist ******"
11 rm -rf $DIST_HOME/*
12 echo "****** Copy new dist ******"
13 mv $TARGET_HOME/dist.tar.gz $DIST_HOME
14 tar -zxvf $DIST_HOME/dist.tar.gz -C $DIST_HOME
15 rm -rf $DIST_HOME/dist.tar.gz
useradd java
passwd java
cd /home/java
wget https://www.oracle.com/webapps/redirect/signon?nexturl=https://download.oracle.com/otn/java/jdk/8u271-b09/61ae65e088624f5aaa0b1d2d801acb16/jdk-8u271-linux-x64.tar.gz
tar -zxvf jdk-8u271-linux-x64.tar.gz
vim /etc/profile
export JAVA_HOME=/home/java/jdk1.8.0_271
export PATH=$JAVA_HOME/bin:$PATH
source /etc/profile
java -version
ln -s /home/java/jdk1.8.0_271/bin/java /usr/bin/java
wget https://binaries.sonarsource.com/Distribution/sonarqube/sonarqube-7.6.zip
cp sonarqube-7.6 /opt
cd /opt/sonarqube/conf
# 修改sonar的配置文件
vim sonar.properties
sonar.jdbc.username=sonar
sonar.jdbc.password=sonar
sonar.login=admin
sonar.password=admin
sonar.jdbc.url=jdbc:mysql://localhost:3306/sonar?useUnicode=true&characterEncoding=utf8&rewriteBatchedStatements=true&useConfigs=maxPerformance&useSSL=false
# 添加sonar用戶(必須以非root用戶啟動(dòng)sonarqube)
useradd sonar
passwd sonar
chown -R sonar:sonar /opt/sonarqube/
chmod -R 755 /opt/sonarqube
su sonar
# 啟動(dòng)sonarqube
cd /opt/sonarqube/bin/linux-x86-64/
./sonar.sh console
安裝過(guò)程中可能會(huì)出現(xiàn)的問(wèn)題:
1)Encounteredanerrorrunningmain:java.nio.file.AccessDeniedExcepti
解決辦法:刪除sonarqube/temp、sonarqube/logs目錄下的所有文件即可;
2)java.sql.SQLException:CannotcreatePoolableConnectionFactory(Accessdenied)
數(shù)據(jù)庫(kù)賬號(hào)授權(quán)有問(wèn)題。
解決辦法:刪除sonar的庫(kù)表,賬號(hào),重新進(jìn)行建表與授權(quán)。
安裝sonar-scanner:
cd /usr/local
# 下載sonar scanner
wget https://binaries.sonarsource.com/Distribution/sonar-scanner-cli/sonar-scanner-cli-4.4.0.2170-linux.zip
# 解壓
tar -zxvf sonar-scanner-cli-4.4.0.2170-linux.zip
# 進(jìn)入到配置文件目錄下
cd sonar-scanner-4.4.0.2170-linux/conf
# 修改sonar-scanner.properties文件:
sonar.host.url=http://localhost:9000(localhost修改為sonarqube所在的IP地址)
[root@localhost /]# rpm -qa | grep mysql
# 若已安裝了MySQL,執(zhí)行刪除命令
[root@localhost /]# rpm -e --nodeps mysql-libs-5.1.73-5.el6_6.x86_64
# 再次執(zhí)行查詢命令,查看是否刪除成功
[root@localhost /]# rpm -qa | grep mysql
# 查詢所有MySQL對(duì)應(yīng)的文件夾
[root@localhost /]# whereis mysql
mysql: /usr/bin/mysql /usr/include/mysql
[root@localhost lib]# find / -name mysql
/data/mysql
/data/mysql/mysql
# 刪除相關(guān)目錄或文件
[root@localhost /]# rm -rf /usr/bin/mysql /usr/include/mysql /data/mysql /data/mysql/mysql
# 驗(yàn)證是否刪除完畢
[root@localhost /]# whereis mysql
mysql:
[root@localhost /]# find / -name mysql
[root@localhost /]#
# 檢查MySQL用戶和用戶組是否存在,如果沒(méi)有則創(chuàng)建
[root@localhost /]# cat /etc/group | grep mysql
[root@localhost /]# cat /etc/passwd | grep mysql
[root@localhost /]# groupadd mysql
[root@localhost /]# useradd -r -g mysql mysql
# 下載MySQL
[root@localhost /]# wget https://dev.mysql.com/get/Downloads/MySQL-5.7/mysql-5.7.24-linux-glibc2.12-x86_64.tar.gz
# 執(zhí)行解壓縮命令
[root@localhost /]# tar xzvf mysql-5.7.24-linux-glibc2.12-x86_64.tar.gz
[root@localhost /]# ls
mysql-5.7.24-linux-glibc2.12-x86_64
mysql-5.7.24-linux-glibc2.12-x86_64.tar.gz
[root@localhost /]# mv mysql-5.7.24-linux-glibc2.12-x86_64 /usr/local/
[root@localhost /]# cd /usr/local/
[root@localhost /]# mv mysql-5.7.24-linux-glibc2.12-x86_64 mysql
[root@localhost /]# mkdir /usr/local/mysql/data
# 更改mysql目錄下所有的目錄及文件所屬的用戶和用戶組,以及權(quán)限
[root@localhost /]# chown -R mysql:mysql /usr/local/mysql
[root@localhost /]# chmod -R 755 /usr/local/mysql
# 編譯安裝并初始化mysql,務(wù)必記住初始化輸出日志末尾的密碼(數(shù)據(jù)庫(kù)管理員臨時(shí)密碼)
[root@localhost /]# cd /usr/local/mysql/bin
[root@localhost bin]# ./mysqld --initialize --user=mysql --datadir=/usr/local/mysql/data --basedir=/usr/local/mysql
# 測(cè)試啟動(dòng)mysql服務(wù)器
[root@localhost /]# /usr/local/mysql/support-files/mysql.server start
# 添加軟連接,并重啟mysql服務(wù)
[root@localhost /]# ln -s /usr/local/mysql/support-files/mysql.server /etc/init.d/mysql
[root@localhost /]# ln -s /usr/local/mysql/bin/mysql /usr/bin/mysql
[root@localhost /]# service mysql restart
#登陸mysql,修改密碼(密碼為初始化mysql時(shí)生成的臨時(shí)密碼)
[root@localhost /]# mysql -u root -p
Enter password:
mysql>set password for root@localhost = password('yourpass');
# 設(shè)置開(kāi)機(jī)自啟動(dòng)
[root@localhost /]# cp /usr/local/mysql/support-files/mysql.server /etc/init.d/mysqld
[root@localhost /]# chmod +x /etc/init.d/mysqld
[root@localhost /]# chkconfig --add mysqld
[root@localhost /]# chkconfig --list
# yum的repos中默認(rèn)是沒(méi)有Jenkins的,需要先將Jenkins存儲(chǔ)庫(kù)添加到y(tǒng)um repos
sudo wget -O /etc/yum.repos.d/jenkins.repo https://pkg.jenkins.io/redhat-stable/jenkins.repo
sudo rpm --import https://pkg.jenkins.io/redhat-stable/jenkins.io.key
yum install jenkins
#安裝完畢后進(jìn)入jenkins配置文件
vi /etc/sysconfig/jenkins
JENKINS_USER="root"
JENKINS_PORT="8081"
service jenkins start
#下載壓縮包
cd /usr/local
wget https://nodejs.org/dist/latest-v12.x/node-v12.19.0-linux-x64.tar.xz
tar -xvf node-v12.19.0-linux-x64.tar.xz
mv node-12.19.0 node
#進(jìn)入到node目錄的bin中,檢查是否安裝成功
cd node/bin
./node -v
#配置軟鏈接,使全局都可以使用node命令
ln -s /usr/local/node/bin/node /usr/bin/node
ln -s /usr/local/node/bin/npm /usr/bin/npm
#配置node文件安裝路徑
cd /usr/local/node
mkdir node_global
mkdir node_cache
npm config set prefix “node_global”
npm config set cache “node_cache”
#在全局下查看node和npm版本
node -v
npm -v
1 #環(huán)境安裝
2 yum -y install gcc gcc-c++ autoconf automake make
3 yum -y install make zlib-devel gcc-c++ libtool openssl openssl-devel
4 #下載壓縮包
5 cd /usr/local
6 wget http://nginx.org/download/nginx-1.9.9.tar.gz
7 #解壓壓縮包
8 tar -zxvf nginx-1.9.9.tar.gz
9 #進(jìn)入nginx目錄
10 cd nginx-1.9.9
11 #設(shè)置安裝目錄為/usr/local/nginx
12 ./configure --prefix=/usr/local/nginx
13 #編譯、安裝
14 make
15 make install
16 #啟動(dòng)nginx服務(wù)
17 cd /usr/local/nginx/sbin
18 ./nginx
修改Nginx配置文件:
1 cd /usr/local/nginx/conf
2 vim nginx.conf
3 server {
4 listen 8801;
5 root /usr/share/nginx/html;
6
7 # Load configuration files for the default server block.
8 include /etc/nginx/default.d/*.conf;
9
10 location / {
11 root /usr/local/operation_analysis/op-web-package/dist;
12 }
13
14 location /op-analysis {
15 proxy_pass http://172.16.239.51:8101/op-analysis;
16 }
17
18 error_page 404 /404.html;
19 location = /40x.html {
20 }
21
22 error_page 500 502 503 504 /50x.html;
23 location = /50x.html {
24 }
25 }
1 useradd java #添加java用戶
2 passwd java
3 cd /home/java
4 wget https://www.oracle.com/webapps/redirect/signon?nexturl=https://download.oracle.com/otn/java/jdk/8u271-b09/61ae65e088624f5aaa0b1d2d801acb16/jdk-8u271-linux-x64.tar.gz
5 tar -zxvf jdk-8u271-linux-x64.tar.gz
6 vim /etc/profile
7 export JAVA_HOME=/home/java/jdk1.8.0_271
8 export PATH=$JAVA_HOME/bin:$PATH
9 source /etc/profile
10 java -version
11 ln -s /home/java/jdk1.8.0_271/bin/java /usr/bin/java
官網(wǎng)下載地址:http://maven.apache.org/download.cgi
1 tar -zxvf apache-maven-3.6.3-bin.tar.gz -C /usr/local/maven
2 vim /etc/profile
3 export M2_HOME=/usr/local/maven/apache-maven-3.6.3
4 export PATH=$PATH:$M2_HOME/bin
5 source /etc/profile
6 mven -version
創(chuàng)建maven工程后,在工程目錄下創(chuàng)建如下所需的文件夾
src/test/resources:存放報(bào)告模板文件
src/test/jmeter:存放jmeter配置文件及測(cè)試腳本
說(shuō)明:
1)這里的resources下放的是報(bào)告模板文件:jmeter-results-report-apitest.xsl等,以及模板用到的資源文件:collapse.png和expand.png (從 apache-jmeter-3.3\extras下復(fù)制而來(lái));
2)jmeter.properties等是jmeter配置文件(從apache-jmeter-3.3\bin下復(fù)制而來(lái)),后綴.jmx為jmeter腳本(后續(xù)只需要把本地調(diào)試通過(guò)的jmeter腳本放入如圖這個(gè)目錄就可以了);
3)如果properties文件有過(guò)更改,則把相關(guān)的propertie文件也復(fù)制到j(luò)meter文件夾里,否則系統(tǒng)會(huì)使用默認(rèn)的jmeter配置文件。
jmeter執(zhí)行結(jié)果文件默認(rèn)保存的不是xml格式,無(wú)法轉(zhuǎn)化成html格式。
jmeter執(zhí)行結(jié)果文件默認(rèn)有很多執(zhí)行數(shù)據(jù)是不保存的,而測(cè)試報(bào)告需要這些數(shù)據(jù)。
打開(kāi)jmeter.properti文件,做如下修改:
1)去掉注釋(#),修改csv為xml。
2) 添加jtl文件結(jié)果參數(shù)
1 jmeter.save.saveservice.data_type=true
2 jmeter.save.saveservice.label=true
3 jmeter.save.saveservice.response_code=true
4 # response_data is not currently supported for CSV output
5 jmeter.save.saveservice.response_data=true
6 # Save ResponseData for failed samples
7 jmeter.save.saveservice.response_data.on_error=false
8 jmeter.save.saveservice.response_message=true
9 jmeter.save.saveservice.successful=true
10 jmeter.save.saveservice.thread_name=true
11 jmeter.save.saveservice.time=true
12 jmeter.save.saveservice.subresults=true
13 jmeter.save.saveservice.assertions=true
14 jmeter.save.saveservice.latency=true
15 jmeter.save.saveservice.connect_time=true
16 jmeter.save.saveservice.samplerData=true
17 jmeter.save.saveservice.responseHeaders=true
18 jmeter.save.saveservice.requestHeaders=true
19 jmeter.save.saveservice.encoding=false
20 jmeter.save.saveservice.bytes=true
21 jmeter.save.saveservice.url=true
22 jmeter.save.saveservice.filename=true
23 jmeter.save.saveservice.hostname=true
24 jmeter.save.saveservice.thread_counts=true
25 jmeter.save.saveservice.sample_count=true
26 jmeter.save.saveservice.idle_time=true
1 <project xmlns="http://maven.apache.org/POM/4.0.0"
2 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3 xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
4 <modelVersion>4.0.0</modelVersion>
5
6 <groupId>APITest</groupId>
7 <artifactId>JMeter</artifactId>
8 <version>0.0.1-SNAPSHOT</version>
9
10 <name>JMeterTest</name>
11 <url>http://maven.apache.org</url>
12 <dependencies>
13 <dependency>
14 <groupId>junit</groupId>
15 <artifactId>junit</artifactId>
16 <version>3.8.1</version>
17 <scope>test</scope>
18 </dependency>
19 <dependency>
20 <groupId>javax.servlet</groupId>
21 <artifactId>servlet-api</artifactId>
22 <version>3.0-alpha-1</version>
23 </dependency>
24 <dependency>
25 <groupId>mysql</groupId>
26 <artifactId>mysql-connector-java</artifactId>
27 <version>5.1.13</version>
28 </dependency>
29 <!-- <dependency> <groupId>org.apache.jmeter</groupId> <artifactId>ApacheJMeter_jdbc</artifactId>
30 <version>2.11</version> </dependency> <dependency> <groupId>com.oracle</groupId>
31 <artifactId>ojdbc14</artifactId> <version>10.2.0.5</version> </dependency> -->
32 <!-- MySql 5.5 Connector -->
33 </dependencies>
34 <properties>
35 <jmeter.result.jtl.dir>${project.build.directory}\jmeter\results</jmeter.result.jtl.dir>
36 <jmeter.result.html.dir>${project.build.directory}\jmeter\html</jmeter.result.html.dir>
37 <jmeter.result.html.dir1>${project.build.directory}\jmeter\html1</jmeter.result.html.dir1>
38 <jmeter.result.html.dir2>${project.build.directory}\jmeter\html2</jmeter.result.html.dir2>
39 <ReportName>TestReport</ReportName>
40 </properties>
41 <pluginRepositories>
42 <pluginRepository>
43 <id>Codehaus repository</id>
44 <url>http://repository.codehaus.org/</url>
45 <releases>
46 <enabled>true</enabled>
47 <updatePolicy>always</updatePolicy>
48 </releases>
49 <snapshots>
50 <enabled>true</enabled>
51 <updatePolicy>always</updatePolicy>
52 </snapshots>
53 </pluginRepository>
54 </pluginRepositories>
55 <build>
56 <finalName>vet2</finalName>
57 <plugins>
58 <plugin>
59 <!—核心插件,用來(lái)執(zhí)行jmx腳本,注意版本號(hào)-->
60 <groupId>com.lazerycode.jmeter</groupId>
61 <artifactId>jmeter-maven-plugin</artifactId>
62 <version>2.7.0</version>
63 <executions>
64 <execution>
65 <id>test</id>
66 <phase>verify</phase>
67 <goals>
68 <goal>jmeter</goal>
69 </goals>
70 <!-- <configuration> <resultsFileFormat>csv</resultsFileFormat> </configuration> -->
71 </execution>
72 </executions>
73 <configuration>
74 <!-- 設(shè)置jmeter生成結(jié)果文件格式 -->
75 <resultsFileFormat>xml</resultsFileFormat>
76 <!-- 設(shè)置忽略失敗是否停止運(yùn)行 -->
77 <ignoreResultFailures>true</ignoreResultFailures>
78 <!-- 設(shè)置結(jié)果是否有時(shí)間戳 -->
79 <testResultsTimestamp>flase</testResultsTimestamp>
80 <generateReports>false</generateReports>
81 <testFilesIncluded>
82 <!-- 指定運(yùn)行的jmeter腳本 -->
83 <jMeterTestFile>*.jmx</jMeterTestFile>
84 </testFilesIncluded>
85 </configuration>
86 </plugin>
87 <!-- <plugin> <groupId>org.apache.jmeter</groupId> <artifactId>ApacheJMeter_jdbc</artifactId>
88 <version>2.11</version> </plugin> -->
89
90 <plugin>
91 <artifactId>maven-compiler-plugin</artifactId>
92 <configuration>
93 <source>1.8</source>
94 <target>1.8</target>
95 <encoding>UTF-8</encoding>
96 <compilerArguments>
97 <extdirs>src\test\jmeter\lib</extdirs>
98 </compilerArguments>
99 </configuration>
100 </plugin>
101
102 <plugin>
103 <!--根據(jù)xsl模版把jtl文件轉(zhuǎn)換成html,官網(wǎng)地址: http://www.mojohaus.org/xml-maven-plugin/examples/transform-saxon.html-->
104 <groupId>org.codehaus.mojo</groupId>
105 <artifactId>xml-maven-plugin</artifactId>
106 <version>1.0.2</version>
107 <executions>
108 <execution>
109 <phase>verify</phase>
110 <goals>
111 <goal>transform</goal>
112 </goals>
113 </execution>
114 </executions>
115 <configuration>
116 <transformationSets>
117 <transformationSet>
118 <dir>${jmeter.result.jtl.dir}</dir>
119 <stylesheet>src/test/resources/jmeter-results-detail-report_21.xsl</stylesheet>
120 <outputDir>${jmeter.result.html.dir}</outputDir>
121 <fileMappers>
122 <fileMapper
123 implementation="org.codehaus.plexus.components.io.filemappers.FileExtensionMapper">
124 <targetExtension>html</targetExtension>
125 </fileMapper>
126 </fileMappers>
127 </transformationSet>
128 <transformationSet>
129 <!-- 可以根據(jù)不同的模版,同時(shí)生成多個(gè)html報(bào)告 -->
130 <dir>${jmeter.result.jtl.dir}</dir>
131 <stylesheet>src/test/resources/jmeter.results.shanhe.me.xsl</stylesheet>
132 <outputDir>${jmeter.result.html.dir1}</outputDir>
133 <fileMappers>
134 <fileMapper
135 implementation="org.codehaus.plexus.components.io.filemappers.FileExtensionMapper">
136 <targetExtension>html</targetExtension>
137 </fileMapper>
138 </fileMappers>
139 </transformationSet>
140 <transformationSet>
141 <dir>${jmeter.result.jtl.dir}</dir>
142 <stylesheet>src/test/resources/jmeter-results-report-apitest.xsl</stylesheet>
143 <outputDir>${jmeter.result.html.dir2}</outputDir>
144 <fileMappers>
145 <fileMapper
146 implementation="org.codehaus.plexus.components.io.filemappers.FileExtensionMapper">
147 <targetExtension>html</targetExtension>
148 </fileMapper>
149 </fileMappers>
150 </transformationSet>
151 </transformationSets>
152 </configuration>
153 </plugin>
154 <plugin>
155 <groupId>org.apache.maven.plugins</groupId>
156 <artifactId>maven-dependency-plugin</artifactId>
157 <executions>
158 <execution>
159 <id>copy-dependencies</id>
160 <phase>prepare-package</phase>
161 <goals>
162 <goal>copy-dependencies</goal>
163 </goals>
164 <configuration>
165 <outputDirectory>${project.build.directory}/jmeter/lib</outputDirectory>
166 <overWriteReleases>false</overWriteReleases>
167 <overWriteSnapshots>false</overWriteSnapshots>
168 <overWriteIfNewer>true</overWriteIfNewer>
169 </configuration>
170 </execution>
171 </executions>
172 </plugin>
173 <plugin>
174 <groupId>org.apache.maven.plugins</groupId>
175 <artifactId>maven-jar-plugin</artifactId>
176 <configuration>
177 <archive>
178 <manifest>
179 <addClasspath>true</addClasspath>
180 <classpathPrefix>lib/</classpathPrefix>
181 <mainClass>theMainClass</mainClass>
182 </manifest>
183 </archive>
184 </configuration>
185 </plugin>
186 <!-- 把resources文件夾下面的文件拷貝到j(luò)meter/html目錄下 -->
187 <plugin>
188 <artifactId>maven-resources-plugin</artifactId>
189 <executions>
190 <execution>
191 <id>copy-resources-html</id>
192 <phase>compile</phase>
193 <goals>
194 <goal>copy-resources</goal>
195 </goals>
196 <configuration>
197 <!-- test可以在環(huán)境變量中定義,也可以將下面寫成絕對(duì)地址 -->
198 <outputDirectory>${project.build.directory}/jmeter/html</outputDirectory>
199 <resources>
200 <resource>
201 <!-- basedir標(biāo)識(shí)所有工程 -->
202 <directory>${basedir}/src/test/resources</directory>
203 <filtering>true</filtering>
204 </resource>
205 </resources>
206 </configuration>
207 </execution>
208 </executions>
209 </plugin>
210 <!-- 把resources文件夾下面的文件拷貝到j(luò)meter/lib/ext目錄下 -->
211 <plugin>
212 <artifactId>maven-resources-plugin</artifactId>
213 <executions>
214 <execution>
215 <id>copy-resources-lib</id>
216 <phase>compile</phase>
217 <goals>
218 <goal>copy-resources</goal>
219 </goals>
220 <configuration>
221 <!-- test可以在環(huán)境變量中定義,也可以將下面寫成絕對(duì)地址 -->
222 <outputDirectory>${project.build.directory}/jmeter/lib/ext</outputDirectory>
223 <resources>
224 <resource>
225 <!-- basedir標(biāo)識(shí)所有工程 -->
226 <directory>${basedir}/src/test/lib</directory>
227 <filtering>false</filtering>
228 </resource>
229 </resources>
230 </configuration>
231 </execution>
232 </executions>
233 </plugin>
234
235 </plugins>
236 <defaultGoal>clean</defaultGoal>
237 </build>
238 </project>
Maven配置說(shuō)明:
jmeter.result.jtl.dir:生成.jtl格式的測(cè)試報(bào)告路徑
jmeter.result.html.dir:生成.html格式的測(cè)試報(bào)告路徑
jmeter-maven-plugin:jmeter執(zhí)行jmx腳本核心插件
jmeterExtensions:配置jmeter擴(kuò)展依賴包
kg.apc:jmeter-plugins-json:2.6:jmeter用來(lái)做json數(shù)據(jù)斷言用的插件
testFilesDirectory:指定jmx文件夾
testFilesIncluded:指定可執(zhí)行測(cè)試腳本
testFilesExcluded:指定不可執(zhí)行測(cè)試腳本
需要安裝的插件:HTML Publisher plugin、Groovy Label Assignment plugin。
因?yàn)镴enkins安全默認(rèn)把如下功能都關(guān)閉了,需要 Groovy 插件執(zhí)行 Groovy 腳本開(kāi)啟:
1、javascript
2、html上的內(nèi)置插件
3、內(nèi)置css或從其它網(wǎng)站的css
4、從其它網(wǎng)站的圖片
5、AJAX
構(gòu)建配置時(shí),填寫如下Groovy腳本,每次構(gòu)建后執(zhí)行這段腳本開(kāi)啟如上功能:
System.setProperty("hudson.model.DirectoryBrowserSupport.CSP", "")。
1)構(gòu)建一個(gè)maven項(xiàng)目。
2)在General模塊中勾選“Groovy script to restrict where this project can be run”,并在“Groovy Script”中輸入上述的代碼。
3)源碼管理
4)構(gòu)建配置
5)構(gòu)建后操作
首先需要?jiǎng)?chuàng)建一個(gè)版本庫(kù),用于存儲(chǔ)該項(xiàng)目本身及其歷史。為此,我們需要在該項(xiàng)目目錄中使用init命令。對(duì)于一個(gè)帶版本庫(kù)的項(xiàng)目目錄,我們通常稱之為工作區(qū):
>cd d:/projects/first-steps
>git init
Init命令會(huì)在上述目錄中創(chuàng)建一個(gè)名為.git的隱藏目錄,并在其中創(chuàng)建一個(gè)版本庫(kù)。
接下來(lái),我們需要將foo.txt和bar.txt這兩個(gè)文件添加到版本庫(kù)中去。第一步,我們要先用add命令來(lái)確定哪些文件應(yīng)被包含在下次提交中。第二步,再用commit命令將修改傳送到版本庫(kù)中:
>git add bar.txt foo.txt
>git commit --meaasge “Sample project imported”
如果我們對(duì)工作區(qū)中的文件進(jìn)行了修改,status命令會(huì)顯示出該項(xiàng)目自上次提交以來(lái)所發(fā)生的所有修改:
>git status
如果我們還想看到更多細(xì)節(jié)性的內(nèi)容,也可以通過(guò)diff命令來(lái)顯示其每個(gè)被修改的行:
>git diff foo.txt
所有的修改都必須要先被歸檔成一次新的提交。我們要對(duì)修改過(guò)的文件和新文件執(zhí)行add命令,并對(duì)要?jiǎng)h除的文件使用rm命令:
>git add foo.txt bar.html
>git rm bar.txt
現(xiàn)在再次調(diào)用status命令,我們會(huì)看到所有的修改已經(jīng)被納入了下一次提交中:
>git status
然后用commit命令提交這些修改:
>git commit –message “Some changes”
log命令可用來(lái)顯示項(xiàng)目的歷史,所有的提交都會(huì)按時(shí)間順序被降序排列出來(lái):
>git log
在Git中,每個(gè)開(kāi)發(fā)者擁有的是一個(gè)屬于他/她自己的、自帶獨(dú)立版本庫(kù)的工作區(qū),因此這已經(jīng)是一個(gè)不依賴于中央服務(wù)器的、完整的版本控制系統(tǒng)了。開(kāi)發(fā)者們可以通過(guò)交換各自版本庫(kù)中的提交來(lái)實(shí)現(xiàn)項(xiàng)目合作。
新開(kāi)發(fā)者首先要有一個(gè)屬于他/她自己的版本庫(kù)副本(也稱為克隆體)。該副本中包含了所有的原始信息與整個(gè)項(xiàng)目的歷史信息。下面,我們用clone命令來(lái)創(chuàng)建一個(gè)克隆體:
>git clone d:/projects/first-steps d:/projects/first-steps-clone
現(xiàn)在的項(xiàng)目結(jié)構(gòu)為:
現(xiàn)在我們來(lái)修改一下first-steps/foo.txt文件,并執(zhí)行以下操作來(lái)創(chuàng)建一次新提交:
> cd d:/projects/first-steps
> git add foo.txt
> git commit --message "A change in the original."
現(xiàn)在,新的提交已經(jīng)被存入了我們?cè)瓉?lái)的first-steps版本庫(kù)中,但其克隆版本庫(kù)(first-stepsclone)中依然缺失這次提交。我們?cè)賮?lái)修改克隆版本庫(kù)中的first-steps-clone/bar.html文件,并執(zhí)行以下操作:
> cd d:/projects/first-steps-clone
> git add bar.html
> git commit --message "A change in the clone."
現(xiàn)在,我們?cè)趦蓚€(gè)版本庫(kù)中各做了一次新的提交。接下來(lái),我們要用pull命令將原版本庫(kù)中的新提交傳遞給它的克隆體。由于之前我們?cè)趧?chuàng)建克隆版本庫(kù)時(shí),原版本庫(kù)的路徑就已經(jīng)被存儲(chǔ)在了它的克隆體中,因此pull命令知道該從哪里去取回新的提交。
> cd d:/projects/first-steps-clone
> git pull
pull命令從原版本庫(kù)中取回了新的修改,將它們與克隆體中的本地修改進(jìn)行了對(duì)比,并在工作區(qū)中合并了兩邊的修改,創(chuàng)建了一次新的提交。這個(gè)過(guò)程就是所謂的合并(merge)。
在拉回(pull)、合并(merge)的過(guò)程完成之后,我們可以用一個(gè)新的log命令來(lái)查看結(jié)果:
> git log --graph
在沒(méi)有參數(shù)的情況下,pull命令只在克隆版本庫(kù)中能發(fā)揮作用,因?yàn)橹挥性摽寺◇w中有默認(rèn)的原版本庫(kù)的連接。當(dāng)我們執(zhí)行pull操作時(shí),也可以用參數(shù)來(lái)指定任意版本庫(kù)的路徑,以便從某一特定開(kāi)發(fā)分支中提取相關(guān)修改。下面的指令能讓我們將克隆體中的修改pull到原版本庫(kù)中:
> cd /projects/first-steps #切換到原版本庫(kù)
> git pull /projects/first-steps-clone master #將克隆體中的修改pull到原版本中
在一個(gè)Git版本庫(kù)中,總是唯一存在著一個(gè)活動(dòng)分支。我們可以用branch命令(不帶選項(xiàng))來(lái)列出當(dāng)前所有的分支。其中用星號(hào)(*)凸顯的就是當(dāng)前的活躍分支:
> git branch
a-branch
* master
still-a-branch
一般情況下,活動(dòng)分支將會(huì)被繼續(xù)用于接受所有新的提交,并將分支指針移動(dòng)至最近的那次提交。當(dāng)然,我們也可以用checkout命令來(lái)改變當(dāng)前的活躍分支:
> git checkout a-branch
下面,我們來(lái)創(chuàng)建一個(gè)新的分支
1)為當(dāng)前提交創(chuàng)建分支:
>git branch a-branch
2)切換到新分支:
>git checkout a-branch
快捷方式,創(chuàng)建并切換分支:
>git checkout -b a-branch
通常情況下,我們可以用checkout命令在分支之間來(lái)回切換。但是,如果這時(shí)候工作區(qū)還存在著一些修改,我們就必須要先決定好如何處理這部分修改。
我們可以通過(guò)branch -d命令來(lái)刪除分支:
1)刪除一個(gè)已被終止的分支:
>git branch -d a-branch
2)刪除一個(gè)打開(kāi)的分支:
如果我們?cè)谠噲D刪除一個(gè)分支時(shí)自己還未轉(zhuǎn)移到不同的分支(例如master分支)上,Git就會(huì)給出一個(gè)警告,并拒絕該刪除操作。如果你堅(jiān)持要?jiǎng)h除該分支的話,就需要在命令中使用-D選項(xiàng):
> git brach -D a-branch
使用merge命令來(lái)進(jìn)行分支合并是Git中最重要的操作之一。我們可以通過(guò)指定分支名稱來(lái)選擇待合并修改的分支。然后,Git會(huì)基于合并的內(nèi)容來(lái)創(chuàng)建一次新的提交。
git merge命令用于合并指定分支到當(dāng)前分支:
>git checkout test # 切換到test分支
>git merge dev # 將dev分支合并到test分支
1)創(chuàng)建一個(gè)普通的標(biāo)簽
在下面的例子中,我們會(huì)為master分支上的當(dāng)前版本創(chuàng)建一個(gè)名為1.2.3.4的標(biāo)簽,并將其注釋為“Freshly built.”:
> git tag 1.2.3.4 master -m "Freshly built."
2)推送某單一標(biāo)簽
推送操作通常不會(huì)自動(dòng)傳送標(biāo)簽。但如果我們明確指定了某個(gè)標(biāo)簽名,該標(biāo)簽就可以被傳送了:
> git push origin V1.0.0
3)將標(biāo)簽傳送到指定的分支(test)上:
>git push origin test V1.0.0
1、遠(yuǎn)程倉(cāng)庫(kù)相關(guān)命令
檢出倉(cāng)庫(kù):$ git clone git://github.com/jquery/jquery.git
查看遠(yuǎn)程倉(cāng)庫(kù):$ git remote -v
添加遠(yuǎn)程倉(cāng)庫(kù):$ git remote add [name] [url]
刪除遠(yuǎn)程倉(cāng)庫(kù):$ git remote rm [name]
修改遠(yuǎn)程倉(cāng)庫(kù):$ git remote set -url --push [name] [newUrl]
拉取遠(yuǎn)程倉(cāng)庫(kù):$ git pull [remoteName] [localBranchName]
推送遠(yuǎn)程倉(cāng)庫(kù):$ git push [remoteName] [localBranchName]
如果想把本地的某個(gè)分支test提交到遠(yuǎn)程倉(cāng)庫(kù),并作為遠(yuǎn)程倉(cāng)庫(kù)的master分支,或者作為另外一個(gè)名叫test的分支,如下:
$git push origin test:master // 提交本地test分支作為遠(yuǎn)程的master分支
$git push origin test:test // 提交本地test分支作為遠(yuǎn)程的test分支
2、分支(branch)操作相關(guān)命令
查看本地分支:$ git branch
查看遠(yuǎn)程分支:$ git branch -r
創(chuàng)建本地分支:$ git branch [name] ----注意新分支創(chuàng)建后不會(huì)自動(dòng)切換為當(dāng)前分支
切換分支:$ git checkout [name]
創(chuàng)建新分支并立即切換到新分支:$ git checkout -b [name]
刪除分支:$ git branch -d [name] ---- -d選項(xiàng)只能刪除已經(jīng)參與了合并的分支,對(duì)于未有合并的分支是無(wú)法刪除的。如果想強(qiáng)制刪除一個(gè)分支,可以使用-D選項(xiàng):$git branch -D [name]
合并分支:$ git merge [name] ----將名稱為[name]的分支與當(dāng)前分支合并
創(chuàng)建遠(yuǎn)程分支(本地分支push到遠(yuǎn)程):$ git push origin [name]
3、版本(tag)操作相關(guān)命令
查看版本:$ git tag
創(chuàng)建版本:$ git tag [name]
刪除版本:$ git tag -d [name]
查看遠(yuǎn)程版本:$ git tag -r
合并遠(yuǎn)程倉(cāng)庫(kù)的tag到本地:$ git pull origin --tags
上傳本地tag到遠(yuǎn)程倉(cāng)庫(kù):$ git push origin --tags
創(chuàng)建帶注釋的tag:$ git tag -a [name] -m 'yourMessage'
對(duì)指定的commit ID創(chuàng)建版本:$ git tag -a [name] [commit ID] -m ‘yourMessage’
查看版本的詳細(xì)信息:$ git show [name]
4、其它命令
改變文件名字:$ git mv old-filename new-filename
刪除文件:$ git rm filename
查看本地目錄和暫存區(qū)之間文件的差異:$ git diff filename
查看暫存區(qū)和本地倉(cāng)庫(kù)之間文件的差異:$ git diff --cached filename
查看提交日志:$ git log、$ git log --oneline、$ git log -n
本地文件誤操作回退:
使用暫存區(qū)內(nèi)容覆蓋本地目錄:$ git checkout filename
本地文件提交至?xí)捍鎱^(qū)后的回退操作:
1)本地倉(cāng)庫(kù)覆蓋暫存區(qū):$ git reset HEAD filename
2)暫存區(qū)覆蓋本地目錄:$ git checkout -- filename
多次提交后會(huì)回退到某個(gè)版本:
$ git log --oneline #查看版本號(hào)
$ git reset --hard <版本號(hào)> #回退到指定的版本號(hào)
1) 除了master分支創(chuàng)建一個(gè)供所有開(kāi)發(fā)人員開(kāi)發(fā)的dev分支;
2) 開(kāi)發(fā)人員在dev分支上進(jìn)行工作,隨時(shí)隨地commit,每天push一次到服務(wù)器;
3) push代碼前需要進(jìn)行pull操作,因?yàn)橛锌赡茉谥坝袆e的成員先進(jìn)行了push操作,如果有沖突還需要進(jìn)行沖突解決;
4) 每天上班后所有成員對(duì)dev進(jìn)行pull操作,獲取所有成員push的代碼,有沖突需要解決;
5) 團(tuán)隊(duì)Leader每天將dev合并一次到master。
1) 測(cè)試進(jìn)入后就需要添加test分支;
2) 在開(kāi)發(fā)人員將代碼push到dev分支后,可以在dev基礎(chǔ)上創(chuàng)建test分支,測(cè)試人員以test分支搭建測(cè)試環(huán)境,開(kāi)始測(cè)試;
3) 開(kāi)發(fā)人員在接收到bug后,直接在測(cè)試分支上修改,然后讓測(cè)試人員進(jìn)行驗(yàn)證;
4) 每天團(tuán)隊(duì)Leader將測(cè)試分支上修改的bug合并到dev分支上,這樣所有團(tuán)隊(duì)成員當(dāng)天修復(fù)的bug都會(huì)在第二天被團(tuán)隊(duì)其他人pull下來(lái);
5) 團(tuán)隊(duì)Leader每天將dev合并一次到master。
1) 系統(tǒng)上線后試運(yùn)行階段會(huì)存在兩種改動(dòng):bug和優(yōu)化需求,bug通常當(dāng)天解決晚上部署,優(yōu)化需求通常周末部署;
2) bug當(dāng)天能修復(fù)的就直接在test分支上修復(fù),然后進(jìn)行測(cè)試,驗(yàn)證通過(guò)后合并到master;
3) bug當(dāng)天不能修復(fù)的就針對(duì)該bug創(chuàng)建一個(gè)分支,修復(fù)完后合并到test分支進(jìn)行測(cè)試,驗(yàn)證通過(guò)后合并到master;
4) 每個(gè)優(yōu)化需求都以master分支為基礎(chǔ)創(chuàng)建一個(gè)feature分支,完成后合并到dev分支,開(kāi)發(fā)人員可以先交叉測(cè)試,然后將dev合并到test進(jìn)行測(cè)試,驗(yàn)證通過(guò)后合并到master;
5) master始終是一個(gè)干凈的,可發(fā)布的分支。
1) 需求或是Bug都是用Issue來(lái)表示;
2) 雖然Issue不支持多層級(jí),但結(jié)合里程碑、標(biāo)簽等還是可以很好的對(duì)任務(wù)和Bug進(jìn)行管理;
3) 管理員和團(tuán)隊(duì)成員都可以進(jìn)行Issue的創(chuàng)建;
4) 任務(wù)的接收者對(duì)Issue創(chuàng)建Merge Request;
5) 完成任務(wù)后推送代碼到Merge Request對(duì)應(yīng)的分支;
6) 管理員對(duì)代碼進(jìn)行Merge。
1)設(shè)置重要分支受保護(hù)
2)創(chuàng)建issue
3)任務(wù)創(chuàng)建后,開(kāi)發(fā)人員就可以根據(jù)該任務(wù)創(chuàng)建Merge Request了
------------------------------
初始化版本庫(kù),并提交到遠(yuǎn)程服務(wù)器端
mkdir WebApp
cd WebApp
git init本地初始化
touch README
git add README添加文件
git commit -m 'first commit'
git remote add origin git@github.com:daixu/WebApp.git增加一個(gè)遠(yuǎn)程服務(wù)器端
上面的命令會(huì)增加URL地址為'git@github.com:daixu/WebApp.git',名稱為origin的遠(yuǎn)程服務(wù)器庫(kù),以后提交代碼的時(shí)候只需要使用origin別名即可。
原文地址:https://www.cnblogs.com/gltou/p/15329634.html
伙伴們,用python做接口自動(dòng)化是不是寫代碼比較繁瑣,而且沒(méi)有python代碼基礎(chǔ)的小伙伴根本無(wú)從下手對(duì)吧!今天我們來(lái)學(xué)習(xí)一下如何使用JMeter工具實(shí)現(xiàn)接口自動(dòng)化測(cè)試。
01 安裝
1、安裝JDK,配置java環(huán)境變量(安裝過(guò)程略)
2、安裝Jmeter(安裝過(guò)程略)
3、安裝ANT
3.1、下載安裝
下載地址:http://ant.apache.org/bindownload.cgi
3.1.1、下載后解壓到指定位置即可,比如:F:\apache-Ant
3.1.2、將jmeter所在的目錄下extras子目錄里的ant-jmeter-1.1.1.jar復(fù)制到ant所在目錄lib子目錄之下,這樣ant運(yùn)行時(shí)才能找到”
org.programmerplanet.ant.taskdefs.jmeter.JMeterTask”這個(gè)類,從而成功觸發(fā)JMeter腳本。
3.2、配置環(huán)境變量
添加環(huán)境變量(以windows為例)
ANT_HOME F:\apache-Ant
CLASSPATH %ANT_HOME%\lib
Path %ANT_HOME%\bin
3.3、驗(yàn)證安裝結(jié)果,命令行輸入ant -version,出現(xiàn)版本信息則安裝成功
2 ANT與Jmeter
4.配置ANT與Jmeter的配置文件
4.1.1、配置ANT配置ant編譯文件build.xml
拷貝下面的內(nèi)容與新建的txt文件中,并將此文件改名為:build.xml
<?xml version="1.0" encoding="utf-8"?><project name="pc" default="all" basedir="F:\apache-jmeter-5.0\jmeterAutoTest">
<tstamp>
<format property="time" pattern="yyyyMMddhhmm" />
</tstamp>
<property name="jmeter.home" value="F:\apache-jmeter-5.0" />
<property name="jmeter.result.jtl.dir" value="F:\apache-jmeter-5.0\jmeterAutoTest\pc\resultlog\jtl" />
<property name="jmeter.result.html.dir" value="F:\apache-jmeter-5.0\jmeterAutoTest\pc\resultlog\html" />
<property name="ReportName" value="TestReport" />
<property name="jmeter.result.htmlName" value="${jmeter.result.html.dir}/${ReportName}${time}.html" />
<property name="jmeter.result.jtlName" value="${jmeter.result.jtl.dir}/${test}${time}.jtl" />
<property name="mail_from" value="xx@163.com" />
<property name="mail_to" value="xx@qq.com" />
<target name="all">
<antcall target="test" />
<antcall target="report" />
<antcall target="send" />
</target>
<target name="test">
<taskdef name="jmeter" classname="org.programmerplanet.ant.taskdefs.jmeter.JMeterTask" />
<jmeter jmeterhome="${jmeter.home}" resultlog="${jmeter.result.jtlName}">
<testplans dir="F:\apache-jmeter-5.0\jmeterAutoTest\pc\script" />
</jmeter>
</target>
<path id="xslt.classpath">
<fileset dir="${jmeter.home}/lib" includes="xalan*.jar"/>
<fileset dir="${jmeter.home}/lib" includes="serializer*.jar"/>
</path>
<target name="report">
<xslt classpathref="xslt.classpath"
force="true"
in="${jmeter.result.jtlName}"
out="${jmeter.result.htmlName}"
style="${jmeter.home}/extras/jmeter-results-detail-report_21.xsl">
<param name="dateReport" expression="${time}"/>
</xslt>
<copy todir="${jmeter.result.html.dir}">
<fileset dir="${jmeter.home}/extras">
<include name="collapse.png" />
<include name="expand.png" />
</fileset>
</copy>
</target></project>
4.1.2、修改build.xml文件,按照實(shí)際的文件路徑配置好
4.1.3 、配置jmeter.properties
配置jmeter報(bào)告輸出格式為xml,在jmeter/bin目錄下jmeter.properties文件中修改jmeter.save.saveservice.output_format=csv為jmeter.save.saveservice.output_format=xml,并去掉前面的注釋符號(hào)#
4.1.4、準(zhǔn)備測(cè)試腳本數(shù)據(jù)
新建文件夾pc,pc文件夾分別新建buildfile ,resultlog,script 三個(gè)文件夾,buildfile文件夾放入build.xml文件,resultlog里分別新建html,jtl文件夾。
注:Resultlog
Html文件夾裝的是ant 轉(zhuǎn)化后的結(jié)果
Jtl文件裝的是meter生成的結(jié)果
Script:Jmeter執(zhí)行的腳本
3 測(cè)試報(bào)告
5、打開(kāi)命令行進(jìn)行build.xml文件所在的目錄,輸入ant即可生成報(bào)告,報(bào)告存放在html文件夾里
生成的測(cè)試報(bào)告如下
6、測(cè)試報(bào)告優(yōu)化
用jmeter自帶的測(cè)試報(bào)告得到的測(cè)試報(bào)告信息并不是很全,這里參考網(wǎng)上的方法,做一個(gè)優(yōu)化
6.1.1、下載優(yōu)化模板jmeter-results-shanhe-me.xsl,拷貝到j(luò)meter的extras目錄中,如C:\apache-jmeter-2.12\extras
6.2.2、設(shè)置測(cè)試輸出報(bào)告要輸出的內(nèi)容,同樣在jmeter.properties中,設(shè)置需要輸出的內(nèi)容為true,并去掉前面的注釋符號(hào)#,這里全部設(shè)置成true
修改前:
修改后:
jmeter.save.saveservice.data_type=truejmeter.save.saveservice.label=truejmeter.save.saveservice.response_code=true# response_data is not currently supported for CSV outputjmeter.save.saveservice.response_data=true# Save ResponseData for failed samplesjmeter.save.saveservice.response_data.on_error=falsejmeter.save.saveservice.response_message=truejmeter.save.saveservice.successful=truejmeter.save.saveservice.thread_name=truejmeter.save.saveservice.time=truejmeter.save.saveservice.subresults=truejmeter.save.saveservice.assertions=truejmeter.save.saveservice.latency=true# Only available with HttpClient4#jmeter.save.saveservice.connect_time=truejmeter.save.saveservice.samplerData=truejmeter.save.saveservice.responseHeaders=truejmeter.save.saveservice.requestHeaders=truejmeter.save.saveservice.encoding=truejmeter.save.saveservice.bytes=true# Only available with HttpClient4
#jmeter.save.saveservice.sent_bytes=truejmeter.save.saveservice.url=truejmeter.save.saveservice.filename=truejmeter.save.saveservice.hostname=truejmeter.save.saveservice.thread_counts=truejmeter.save.saveservice.sample_count=falsejmeter.save.saveservice.idle_time=true
6.2.3、設(shè)置build文件的報(bào)告模板為優(yōu)化后的模板jmeter-results-shanhe-me.xsl
6.2.4、按前面的方式再次用ant構(gòu)建測(cè)試,查看優(yōu)化后的測(cè)試報(bào)告
、為什么用命令行模式
使用GUI方式啟動(dòng)jmeter,運(yùn)行線程較多的測(cè)試時(shí),會(huì)造成內(nèi)存和CPU的大量消耗,導(dǎo)致客戶機(jī)卡死;
所以一般采用的方式是在GUI模式下調(diào)整測(cè)試腳本,再用命令行模式執(zhí)行;
命令行方式支持在多個(gè)環(huán)境下使用,windosw的dos環(huán)境下,也可以在linux環(huán)境上執(zhí)行。
注意:使用命令執(zhí)行jmeter腳本必須使用jmeter 3.0及以上版本。
2、怎么用
2.1、執(zhí)行命令
jmeter -n -t <testplan filename> -l <listener filename>
示例: jmeter -n -t testplan.jmx -l test.jtl
示例含義:表示以命令行模式運(yùn)行testplan.jmx文件,輸出的日志文件為test.jtl
2.2、參數(shù)介紹
Jmeter官方手冊(cè)給的介紹如下:
-h, –help -> prints usage information and exit
-n, –nongui -> run JMeter in nongui mode
-t, –testfile <argument> -> the jmeter test(.jmx) file to run
-l, –logfile <argument> -> the file to log samples to
-r, –runremote -> Start remote servers (as defined in remote_hosts)
-H, –proxyHost <argument> -> Set a proxy server for JMeter to use
-P, –proxyPort <argument> -> Set proxy server port for JMeter to use
中文釋義:
-h 幫助 -> 打印出有用的信息并退出
-n 非 GUI 模式 -> 在非 GUI 模式下運(yùn)行 JMeter
-t 測(cè)試文件 -> 要運(yùn)行的 JMeter 測(cè)試腳本文件
-l 日志文件 -> 記錄結(jié)果的文件
-R 遠(yuǎn)程執(zhí)行 -> 遠(yuǎn)程執(zhí)行機(jī)的IP(ip地址)如果有多個(gè)ip時(shí),使用-R 192.168.2.170,192.168.2.171(分布式使用)
-r 遠(yuǎn)程執(zhí)行 -> 在Jmter.properties文件中指定的所有遠(yuǎn)程服務(wù)器(分布式使用)
-H 代理主機(jī) -> 設(shè)置 JMeter 使用的代理主機(jī)
-P 代理端口 -> 設(shè)置 JMeter 使用的代理主機(jī)的端口號(hào)
2.3、執(zhí)行過(guò)程
命令:jmeter -n -t C:\Users\yzs\Desktop\Unione_performance.jmx -l report-result.jtl
不在jmeter安卓目錄執(zhí)行腳本的前提是配置了jmeter的環(huán)境變量。
上述的命令有測(cè)試結(jié)果保存到D:\report中,在GUI模式下查看測(cè)試報(bào)告:
1、在測(cè)試計(jì)劃下,添加對(duì)應(yīng)的測(cè)試報(bào)告元件,舉例增加了:查看結(jié)果樹(shù)、聚合報(bào)告
2、在“所有數(shù)據(jù)寫入一個(gè)文件”,選擇加載對(duì)應(yīng)的結(jié)果文件
3、下面就會(huì)有對(duì)應(yīng)的表格展示,具體見(jiàn)下圖
2.5、命令行傳遞變量值
設(shè)置線程組的線程數(shù)和循環(huán)次數(shù)。
注意格式:
${__P(threadNum)}
${__P(threadCount)}
其中P前面是兩個(gè)下劃線,()內(nèi)就是變量名
執(zhí)行時(shí),在命令行中用-J參數(shù)給變量賦值即可:
jmeter -n -t C:\Users\yzs\Desktop\Unione_performance.jmx -J threadNum=10 -J threadCount=2 -l report-result.jtl
此次測(cè)試相當(dāng)于:10個(gè)線程,循環(huán)2次,共計(jì)20個(gè)請(qǐng)求。
3、生成HTML報(bào)告
生成HTML報(bào)告有2種方式,一種是直接在命令行加上-o參數(shù),另一種是已有jtl結(jié)果文件,運(yùn)行命令生成報(bào)告
3.1、命令行直接生成報(bào)告
jmeter -n -t 【Jmx腳本位置】-l 【中間文件result.jtl位置】-e -o 【報(bào)告指定文件夾】
-e:測(cè)試結(jié)束后,生成測(cè)試報(bào)告
-o:指定測(cè)試報(bào)告的存放位置
注意:-o后面跟的文件夾一定是不存在的或者是空文件夾
3.2、已有jtl結(jié)果文件,運(yùn)行命令生成報(bào)告
jmeter -g【已經(jīng)存在的.jtl文件的路徑】-o 【用于存放html報(bào)告的目錄】
注意:經(jīng)實(shí)操,windows系統(tǒng)上,以上2種方法都可以生成HTML測(cè)試報(bào)告,但是在Linux系統(tǒng)上第1種方法,沒(méi)有生成報(bào)告,只有第二種方法才可以(具體原因后面在慢慢找吧)
3.3、HTML報(bào)告注解
用瀏覽器打開(kāi)index.html
報(bào)告詳解
Dashboard:(重點(diǎn)查看)
Test and Report informations:指的是測(cè)試和報(bào)告信息
APDEX(Application Performance Index):應(yīng)用程序性能滿意度的標(biāo)準(zhǔn)
其中,
Requests Summary:請(qǐng)求的通過(guò)率(OK)與失敗率(KO),百分比顯示
Statistics:數(shù)據(jù)分析,基本將Summary Report和Aggrerate Report的結(jié)果合并(平均響應(yīng)時(shí)間、TPS在此查看)
Errors:錯(cuò)誤情況,依據(jù)不同的錯(cuò)誤類型,將所有錯(cuò)誤結(jié)果展示
關(guān)于Apdex的補(bǔ)充:
性能指數(shù),Apdex(Application Performance Index)是一個(gè)國(guó)際通用標(biāo)準(zhǔn),Apdex 是用戶對(duì)應(yīng)用性能滿意度的量化值。它提供了一個(gè)統(tǒng)一的測(cè)量和報(bào)告用戶體驗(yàn)的方法,把最終用戶的體驗(yàn)和應(yīng)用性能作為一個(gè)完整的指標(biāo)進(jìn)行統(tǒng)一度量。下圖表示為通用用戶滿意度區(qū)域,0代表沒(méi)有滿意用戶,1則代表所有用戶都滿意。實(shí)際業(yè)務(wù)系統(tǒng)開(kāi)發(fā)過(guò)程中,1是團(tuán)隊(duì)的追求目標(biāo)。
若所有請(qǐng)求的Apdex值都接近1,說(shuō)明用戶滿意度優(yōu)秀,也從側(cè)面說(shuō)明了服務(wù)器響應(yīng)速度快。
通常而言,最低要求超過(guò)0.5,當(dāng)然項(xiàng)目組可設(shè)定具體需求。
Charts:(輔助分析)
主要有如下特點(diǎn):
(1)將測(cè)試過(guò)程中經(jīng)常使用的數(shù)據(jù),用圖表的形式展示,讓測(cè)試結(jié)果更加直觀
(2)每個(gè)圖表數(shù)據(jù),有兩種展示形式
(3)支持請(qǐng)求樣例過(guò)濾顯示
(4)支持導(dǎo)出PNG圖片格式
Over Time Charts:
Throughput Charts:
Response Times Charts:
3.4、HTML報(bào)告的自定義配置
JMeter3.0開(kāi)始在bin目錄新增了reportgenerator.properties文件保存了所有關(guān)于圖形化HTML報(bào)告生成模塊的默認(rèn)配置,要變更配置,建議不要直接編輯該文件,而是推薦在user.properties中去配置和覆蓋。
3.4.1總體配置
總體配置都是以jmeter.reportgenerator.為前綴,如:jmeter.reportgenerator.overall_granularity=60000
# Change this parameter if you want to change the granularity of over time graphs.
jmeter.reportgenerator.overall_granularity=6000
Apdext = (Satisfied Count + Tolerating Count / 2) / Total Samples
另外,在jmeter.properties中,有關(guān)于集合報(bào)告中的三個(gè)百分位的默認(rèn)值:
aggregate_rpt_pct1 : Defaults to 50
aggregate_rpt_pct2 : Defaults to 70
aggregate_rpt_pct3 : Defaults to 99
3.5、HTML報(bào)告的定制
JMeter的HTML報(bào)告生成時(shí)是使用了固定的模板,模板文件路徑為./bin/report-template。
進(jìn)入該目錄可以看到報(bào)告的每個(gè)頁(yè)面都有一個(gè).fmkr模板文件,包括index.html.fmkr和./content/pages路徑下的幾個(gè)文件。通過(guò)查看這些模板文件,就可以知道怎樣去進(jìn)行報(bào)告的輕度定制,比如將一些文本修改得更易懂,或者修改為中文等
頁(yè)面的title
默認(rèn)為"Apache JMeter Dashboard"
可以由reportgenerator.properties中的jmeter.reportgenerator.report_title來(lái)統(tǒng)一定義,這種方式就是所有頁(yè)面的title都使用同一個(gè)。
也可以直接修改對(duì)應(yīng)的.fmkr文件中的title標(biāo)簽中雙引號(hào)內(nèi)的值,如<title>${reportTitle!"想要設(shè)置的title"}</title>,這中方式可以為每個(gè)頁(yè)面單獨(dú)定義title
圖表的名稱
當(dāng)前版本下,各圖表的名稱是直接在模板文件中定義,要修改也是直接修改模板文件中對(duì)應(yīng)元素的值即可
如要修改Transactions Per Second圖表的名稱,可以直接在./content/pages/Throughput.html.fmkr文件中修改,效果如下圖
*請(qǐng)認(rèn)真填寫需求信息,我們會(huì)在24小時(shí)內(nèi)與您取得聯(lián)系。