如何組織一場JAVA技能大練兵

程式設計師順仔發表於2021-01-02

近期,公司為了鍛鍊開發人員技能,舉辦了一場涵蓋多個技術線的技能大練兵,我有幸受邀負責java技術方向的出題和評審工作。下面從以下幾個方面回顧下整個過程:

  • 題目設計
  • 程式要求
  • 測試方法

題目設計

題目設計主要考慮以下幾點:

  • 技術演進需求:在公司系統雲遷移的戰略背景下,我們的應用即將從原來傳統的虛擬機器部署向PAAS雲環境進行大規模遷移,需要開發人員掌握雲環境的開發技能,應用開發框架需要從原來的SpringMVC+dubbo升級為SpringCloud服務治理框架。

  • 新老員工兼顧:目前公司的開發人員構成中,入職一兩年的新員工超過一半,題目設計需要考慮到新員工的技能水平,不宜難度過大,否則會打消新員工參與的積極性。同時,還需要能體現正真的技術實力,不能因為題目過於簡單而使得分數拉不開差距。因此,題目設計要使大家都能完成基本功能,同時拿高分的難度較大。

  • 解決生產難題:大練兵的初衷就是鍛鍊開發人員技術實力,提升企業級應用的開發技能,更好的完成日常任務,最終要解決生產難題,保障線上系統穩定。類似力扣網上的演算法題,不適合作為此次大練兵的題目。

基於以上幾點考慮,最終題目設計如下:

完成一個交易系統:
產品子系統(product)、訂單子系統(order)、積分經驗子系統(experience),3個子系統完成分散式部署和呼叫。
業務場景:
一筆交易過程中,產品子系統要扣減庫存,訂單子系統要新增訂單,積分子系統要有相應的積分增加。積分規則為每消費1元增加1積分。

功能要求:

完成5只介面:下單、查詢庫存、查詢訂單、查詢積分、個人交易資訊概覽

題目意在考察大家在完成基本功能的同時,如何保證資料的一致性。

程式要求

根據前期統計的報名意向來看,預計會有50人左右提交比賽交付物。這麼多交付物如果要依靠線下演示評審打分的話,週期很長,而且需要人工部署除錯,帶來巨大的工作量。因此,必須使用自動化的方式進行打分。同時為了控制程式實現範圍,防止開發人員無限蔓延開發需求,增加過多考察範圍之外的擴充套件,因此對程式做了以下限制:

  • 中介軟體限制:由於本次大練兵意在為後續的雲遷移做技術儲備,因此中介軟體的選型必須控制在雲上中介軟體的範圍內,因此要求使用SpringCloud+consul的服務治理框架、Nginx軟負載等中介軟體,不能使用Apache、Dubbo等雲上不用的中介軟體。

  • 資料格式:題目提供3個子系統中核心的資料庫表結構,例如產品資訊表、訂單資訊表、使用者經驗表等。同時給出5個介面的上送和返回欄位,所有人必須按照此格式對前提供服務。

  • 組包格式:由於決定要實現自動化的打分程式,就必須要統一組包要求,包括壓縮包的目錄層級結構、sql指令碼格式、nginx配置檔案、start和stop指令碼等。題目要求必須實現3個模組(product、order、experience),同時提供了一個可選的其它模組(other),參賽者可根據需要自己實現,如閘道器、聚合服務等功能都可以放在other模組實現。other模組組包要求同其它3個模組一致。

本次題目主要的考察難點是如何保證資料的一致性。但是由於測試環境是同網段的機器,內網測試環境非常穩定,在正常的程式執行過程中,很難發生資料不一致的情況。如何產生使資料可能不一致的事件,是本次出題的重點。

因此除了以上幾個限制,本次大練兵還引入了一個大殺器:chaos-monkey。

chaos-monkey:是由netflix開源的一款軟體,它能在生產系統中隨機產生異常事件,包括超時、程式異常、當機等。chaos-monkey的想法源自於“混沌工程”。

混沌工程,是一門對系統進行實驗的學科,旨在瞭解系統對應生產環境各種混亂狀況的能力,建立對系統的信心。通過開展混沌工程方面的實驗,可以測試出系統是否存在缺陷,從而瞭解系統在混亂的生產條件下如何表現。

chaos-monkey的原則,避免大多數失效的主要方式就是經常失效。通過經常在生產環境製造故障,以保證生產環境的彈性。

本次比賽提供了chaos-monkey的jar包和配置,要求參賽者必須引入,以模擬超時或者異常,從而引發資料不一致,測試程式的健壯性。

測試方法

測試主要分為兩步驟:自動部署和自動測試。

服務拓撲圖如下:

自動部署

所有選手的交付物都提交到統一的ftp目錄,因此從ftp中遍歷檔案並觸發部署即可。

流水線步驟如下:

for(遍歷ftp上的包)
    清除redis快取
    執行題目提供的sql建表語句,初始化資料庫
    從FTP獲取壓縮包,並解壓
    If(有nginx配置檔案)
	替換nginx配置檔案,並過載
    else
	分發預設的nginx配置檔案,並過載
    執行鋪底資料指令碼
    For(遍歷服務個數)
	按規則將各個服務壓縮包分發至各服務節點
	if(存在額外的init.sql)   
            執行init.sql
	執行服務的啟動指令碼start.sh
    執行測試指令碼,收集測試結果,計算分數,並輸出到CSV檔案
    停止各服務

通常情況下,自動部署使用Jenkins實現。但是Jenkins不支援迴圈遍歷,一個job只能完成一個參賽者的部署和測試。如果每個參賽者一個job,不能保證每個job配置的正確性,並且由於只有一套評審環境,每個人一個job的話,不能保證job的序列執行,多個job同時執行會相互影響。因此決定自己編寫部署指令碼,僅在部署完成後,需要測試時觸發測試job,由測試job完成測試和打分。部署指令碼監聽測試job的狀態,測試完成後,再開始執行下個參賽者的部署流程。

自動化測試

公司本來就具備完善的Robot Framework自動化測試基礎設施,本次測試直接使用即可。由於部署程式已經在程式啟動前完成了資料庫和快取的初始化,因此測試程式僅需讀取測試資料並向Nginx發起呼叫即可。

由於要測試程式異常時,資料的一致性,因此要在測試開始之前開啟chaos-monkey,在執行寫入資料的邏輯後(即下單介面),關閉chaos-monkey,再開始查詢,通過查詢各個介面的資料並於寫入的資料相比對,驗證資料的一致性,並打分,步驟如下:

1.開啟各服務的chaos-monkey功能;

2.執行寫資料的測試指令碼,即呼叫數百次下單介面;

3.關閉各服務的chaos-monkey功能;

4.執行單個資料查詢介面,驗證每個介面的可用性,並記錄分數;

5.執行組合驗證邏輯,驗證多個服務的資料一致性,並記錄分數。

每個參賽者的測試執行完成後,要將計算的分數寫入彙總到csv檔案中。拿到最終的csv檔案後,即可利用excel實現按照成績排序。

思考

通過本次大練兵,有以下幾點思考:

  • 工具建設要持續投入:工具建設可使用最小的成本,獲取最大的收益。此次練兵,開發部署流水線和自動化測試指令碼各投入1人,僅在2周內使用業餘時間就完成了開發和測試,比人工部署、演示、測試的成本要低得多。同時工具可重複執行,每次修改完後自動觸發。日常的開發和測試過程應儘可能多的使用工具去做迴歸測試,避免人為疏忽引起的分析遺漏而沒回歸覆蓋。
  • 環境問題不容忽視:每個人都能在自己的環境中跑通程式,但是在評審環境中,有些程式卻無法執行。因此在日常測試過程中,我們除了程式本身的正確性以外,還需關注環境差異可能帶來的問題。這裡順帶吐槽一下,如果公司能使用docker等容器技術,將會提升我們的版本質量,降低因環境不同而出錯的概率。
  • 規範意識有待提高:雖然題目中已經將組包格式、程式埠等做了要求,也已將注意點通知到所有人,但是還是有很多人沒有遵守,導致測試程式跑分較低。這反映出大部分開發人員的特點,只管悶頭寫程式碼,卻忽視了規範要求,導致日後返工,甚至產生線上故障,導致嚴重的後果。建議大家在日常編碼之前,提前熟悉並遵守規範和要求,避免走彎路。

最後,感謝大家對我的容忍。2021,願所有程式都不出bug!

相關文章