還記得第一次寫程式嗎?

記得在我決定要學 PHP 後,首先是找新手教學。教學第一課,通常都是寫 Hello World。接著一開始會教如何安裝 PHP 環境,記得是用 WAMP

環境裝好後,接著要用文字編輯器寫一個檔案 helloworld.php 如下:

<?php

echo 'Hello World';

?>

然後會教檔案要存在哪個資料夾裡,WAMP 預設是放在 C:\wamp\www。接著,開瀏覽器在網址上打 http://localhost/helloworld.php,恭喜,第一個 PHP 程式寫好了。教學通常會給一個範例圖片:

helloworld

即使是最簡單的 Hello World,在實際執行時,也會出現一些錯誤。最常見的,比方說 Syntax Error,因為少打了分號 ;,或是 404 not found,因為網址打錯或檔案放錯地方。遇到這些常見錯誤,通常都能很快解決。經過多次嘗試和修正,最終都能看得到像範例結果圖片一樣的內容。

Hello DevOps

或許有人會覺得很奇怪,怎麼標題與內容不符,突然變成 PHP 新手教學了?非也非也,小小的 Hello World 的教學裡面,其實可以發現一些 DevOps 的影子。

我們來試著了解實作程式的步驟,大概可以分成下面幾個流程:

  1. 準備環境: 即安裝 WAMP
  2. 寫程式:helloword.php 程式
  3. 部署程式: 把程式存到 C:\wamp\www
  4. 測試程式: 測程式通常會有固定的方法,此例為開瀏覽器並在網址列上輸入 http://localhost/helloworld.php
  5. 驗證結果: 承 4,也會有固定的驗證方法,此例為範例圖
  6. 除錯: 即後面的 FAQ 遇到問題並解決的過程

回頭對照一下平常開發工作的內容,可以發現:

  • 1, 3 是維運的工作
  • 2, 6 是開發的工作
  • 4, 5 是測試的工作

各公司分工方法不同,不過單純看工作性質,是可以大略這樣分的。

咦?是不是簡單的一個 Hello World 程式,就讓大家輕鬆達成 DevOps 了嗎?不不,當然不只有這樣,我們再深入一點看:

  • 因為知道部署程式的方法,因此修改完程式後,進入測試階段的速度會非常快
  • 因為有範例圖,所以在寫程式之前,已經知道結果為何了,因此會非常快就知道測試結果是否正確
  • 因為都是同一個人執行所有流程,因此資訊完全透明,這時會發現問題 feedback 並修正的效率超級高

尤其是最後一點,我們可以發現,三個角色的資訊透明,對開發速度會有一定程度的幫助。可能會有人想:也許我們可以從 Hello World 程式角度,去思考如何讓其他專案都能加速開發。

是的!原理與觀念並不難,因此快速開發不會是空談,但實際付諸執行並不是那麼容易的。

我也還在這條偉大的航道上努力中…


回顧一下上例 PHP 的 Hello World,它是寫完程式存檔(準備測試),打開瀏覽器或按重新整理(進入測試),畫面跟結果不符(得知結果),就改程式直到看到正確結果(修正錯誤)。

我們約略可以猜想得到,如果每次修改程式,都能進入測試,並得知結果,接著就能立即修正錯誤,最終就會產出正確的程式。更進一步地,如果每次的修改都去關心結果正確與否,是不是就可以更快速地得到正確結果?

沒錯!每次對程式修改都要去做驗證,這正是本次主題--CI 的精神。

什麼是 CI ?

CI 的全名為 Continuous Integration,中文大部分翻譯「持續整合」。來看英文原本的含意:continuous 帶有連續不間斷,並長久保持下去的意思;integration 則是有把兩個以上的東西組合起來的意思。

對於 Hello World 例子而言,integration 指的是「環境」、「程式」與「瀏覽器」三者組合會出現如範例圖的結果。如果沒出現正確結果,就要 continuous 修改並繼續 integration 直到出現正確結果。換句話說,持續修改程式,並驗證程式是不是正確,就是「持續整合」。

可能有人會覺得這根本是廢話。開發不就「改完程式就驗證」,不然要幹嘛?

是的!我認為 CI 的精神就是如此的廢話又簡單!但從這基礎延伸出來的要領可不簡單!首先我們可以思考,「改完程式就驗證」這句話有幾個重要細節是不確定的:

  • 驗證頻率: 要改到什麼程度才做驗證
  • 驗證範圍: 要驗證到多完整
  • 結果回饋: 驗證正確應該沒什麼問題,但驗證失敗後該採取什麼對策?

其實驗證就跟健康檢查一樣:常做檢查,檢查項目完整,有病就快醫,這樣是最好的。相信大家都知道的--預防勝於治療嘛!

對程式而言,要預防與治療的是 Bug。有趣的是,bug 剛好跟癌細胞很像,它會長大,會擴散,還會轉移。到了末期,幾乎是無法根治。舉幾個例子相信大家都很有感:

  • 長大:某個 function 有個小 bug 懶得改,過一段時間回頭發現它變得很難改了
  • 擴散:class A 被很多 class 使用,可是用久了之後才發現有 bug 而且很難改(因為會長大),然後就慘了,因為只能從其他 class 去配合調整
  • 轉移:承上,當修正 class A 的 bug 後,換其他 class 調整過程出現 bug
  • 末期:程式的 bug 會寫入錯誤的資料進資料庫,如密碼加鹽的過程有錯。這種情況下完全無法判斷與修正。

Bug 大家都很怕,而相信大家也都知道,最好的對策就是「早期發現,早期治療」!越早修正 bug,擴散到其他程式的機率就越小。不管對開發、維運甚至是老闆而言,唯有做到時常為程式健康檢查--也就是「持續整合」--,才是真正能讓企業風險與成本降到最低的方法。

當沒有 CI 的時候

舉實際遇到的幾個反例:

  • 前端人員程式寫好後不做驗證,因為他認為後端沒完成,不能驗證
  • 後端人員程式寫好後不做驗證,因為他說測試人員測過就好
  • 測試人員測完發現有問題卻不修改,因為修改時間過長,老闆決定從業務面 workaround,先上再說

這個反例,簡單來說就是:

  • 開發人員不願幫程式做健檢
  • 測試人員健檢又不完整
  • 程式在健檢不完整的情況都發現有病了,老闆又硬要程式帶病上陣

當然電腦不會病死,但因為長期健檢不完整,程式出現癌細胞都沒有人發現。有天,某個健檢項目(指某個功能)老闆不允許不過,可是測試人員一直健檢不過,開發人員才終於發現,原來這是癌細胞的併發症。因為癌細胞存在很久了,所以同時也發現,癌細胞已經擴散到程式各處,也很難根治了。這份程式因驗證不完整,通常我們也稱它 Legacy code

今天只是初步了解問題,而學習 CI 正好可以避免上述絕大多數的問題。

好 CI,不學嗎?

今日回顧

  • Hello World 也很 DevOps 哦!
  • CI 的精神--改完程式就驗證,而且要時常驗證!
  • Bug 如同癌細胞一樣,不管它就會越來越可怕!
  • 對 bug 最好的對策就是:早期發現,早期治療!
  • CI 精神正是 bug 的剋星!

下一篇:Agile 與 CI 之間的火花

相關連結