微服務所帶來的彈性,以及它與CI/CD,與敏捷等所帶來的效率,讓你心動不已嗎?

微服務和容器、CI/CD、Kubernetes、敏捷等概念有著互相增強彼此所帶來效益的能力。這幾年伴隨著各類技術的發展,台灣自然也沒少了這股熱潮,而這樣的趨勢仍然還在沸騰中。身為一個技術工作者,或許早已看不慣公司裡陳年的大系統,正想一展長才,響應潮流,而管理者或許因為數位轉型與創新的壓力,開始希望從這熱潮中,找尋成功的方程式。

微服務並不是去年才出來的概念,而自家的系統也不是今天才開始運行。先想想「值得嗎?」

微服務是首要之務嗎?

重構系統將其微服務化是一件極大的工程。相信大家對於微服務所帶來的好處朗朗上口,然而分散式系統的管理複雜度和資源的額外開支,在朗朗上口之餘,也必須認真對待。另外,在過程中可能帶來的業務穩定性衝擊與業務發展資源不足的問題。更重要的是,它所帶來的效益不見得如你所想像的!這幾年穿梭在各類系統架構中,常常必須苦惱不已地進行抉擇,分享幾個思考點,或許能夠在大家踏上旅程前,先想想是否已經可以無悔走上重構:

  1. 原先系統的狀態

    向原先系統磨刀霍霍之前,先想想「目前原先系統修改的需求高,修改頻繁的發生嗎?」、「大多數新的實作是否仍然增加在原先系統,還是其他服務裡?」如果,原先系統已經處在維護狀態,或者是新的實作大都與原先系統無關,那麼或許更重要的是在流程或其他面向上的優化。

  2. 系統已經可預期或已出現容量瓶頸

    原先的設計已經限制住系統本身處理當前或者是未來的使用量。如果時常進行尖峰調度,而且調度應變困難,抑或者調度也很難再處理使用量的增長。那麼首要之務,找出瓶頸的服務接口與對應功能類別。作為之後,首要改善之所。

  3. 工程資源

    任何的改善變更都需要。如果工程人員已經吃緊,而又另外增加重構改善等任務,那麼下場很可能是不減反增的技術債、業務進展發生開發瓶頸、與惡化的勞動條件。人永遠不是資源,而是企業成長的夥伴!持續性地超支所衍生的代價,恐怕會降低重構的成功機率,以及削減重構所帶來的效益。

  4. 原始設計是否良善

    單體式(Monolith)架構其實也沒什麼罪惡。如果原始設計已經維持著良好結構,也能正確體現低耦合與高凝聚等特性。那麼它的後續維護其實不見得比較難。難以維護往往是因為求快的實作,導致軟體內部設計耦合度過高,牽一髮動全身,發生問題還無處找之類的狀況。因此,不管在任何時候都好好設計軟體,會讓自己後顧之憂少許多。一個隨便實作的微服務,其實也沒比良善實作單體服務高明到哪?更甚而是不僅要面對可怕的設計外,還要負擔分散式管理的複雜,恐怕問題只是雪上加霜。

如果面對一個既有系統時,已經發生容量問題,設計又差,時常又要新增功能,往往耗損在應對,而非新發展,那麼或許重構是幾乎是你首選了,盤點一下人力狀況和工作配比,為自己重構之路爭取一些支援,反而是你現在該煩惱的,而非是要重構或不重構了。

然而,世事總是讓人陷入兩難,大多數情況都是有點糟,但不是太糟,那麼?

大多數都會是上述狀況,至少我常看到的是如此,那請額外考量機會成本所需資源程度 (如工時、預算、既有工具,etc)。如果發現自己有能力,且CP值高,那麼恭喜你,你應該找得到讓這個重構成功啟動的合理理由。

雋永的旅程還是短暫的火花?

如果準備好充分的理由,那麼為重構啟動一個新的專案,不是一件難的事情。難的往往是啟動後的衝擊與 Day 2 折磨。不是因為過往的職涯經驗,大都是產品導向,因此對於「專案」有深刻的不舒服感。

「專案」很好,麻煩在於所要處理的問題類型!

專案往往有些明顯的特性,比方說「對於完善計畫的依賴」、「明確的起迄,明確而獨佔的資源」、「隔離於交付後的狀況」。 當因為重構而建立一個跨組織的虛擬團隊時,即便有明確的起迄,在那段時間內也會對原先單位的資源調度產生衝擊與成員摩擦等問題,而且評估重構所產生的影響與資源,初期階段往往容易趨向樂觀,而導致後續期程滑動,因此明確的起迄,其實也沒這樣現實,而且也可能會導致品質的下滑,畢竟專案是階段性的,很容易缺乏 Day2 的「Ownership」概念。另外。還必須注意到的是,當採用微服務重構系統時,也會同時發生工具和設計相關的領域知識改變,所以真能夠在「專案結束後」,就甩到另一個團隊身上嗎?
因此考量重構時,應該讓重構進入每個單位的日常工作安排中,或者是進行對應的組織改動,以便讓重構後的成果能夠持續。

變與不變

當討論重構的時候,第一個聯想到的肯定是改變。然而,其實更需考慮的是哪些事情應該保持不變,並且使它更加強健完整:

  1. 技術、工具、與協定

    跟遊戲一樣,你現在有機會「restart」,你打算使用相同工具、套件、技術、和交互介面嗎?

    當發生重構,將有機會採用新的程式語言、最新版本的套件(甚至是同類型,但更強大的套件)。身為工程師,很容易為此就開始熱血沸騰,然而,要謹記在心的是「改變中的改變」所造成的複雜度,除非原先套件有明確的缺失、前景堪憂、或者是有明確的需求,否則,保守一些的選擇都會是比較好的。改變是為了創造價值,而非創造麻煩。除非新的選擇掌握度很高,不然後續有明確的需要,再做改善都還來得及。另外,盡量讓使用者對於變更無感,這邊的無感指的是操作上的無感,因此,保持原先交互介面是個很好的決定,甚至是將原先系統變成單純的Facade都是個不錯的選擇。

  2. 測試

    「自動化測試案例」的重要性,再怎樣強調都不為過。藉由測試可以讓開發者更容易了解系統原先設計的來龍去脈,而且功能測試與端到端測試,還能用於後續改善與遷移時的效能測試,也能夠作為日常功能監測的工具。因此,如果原先系統缺乏測試案例,那麼第一件事就是補足測試;如果原先系統自帶測試案例,那麼就運行它,確保它仍然是有效的。

承諾

任何的改變如果得不到管理層的支持,都將十分難以為繼。尤其重構系統,代表著下面兩項無可避免的承諾確保:

  1. 資源

    調度原先的人力去進行另一項任務,必然會產生人力的缺口,或者是對其他業務的影響。另外,重構過程所導致的新工具導入,也會產生花費。因此,免不了要錢要人,透過清晰、自信且有耐性地獲得相關的承諾是必要的工作。

    更重要的是,讓重構與效益掛勾,並且透過漸進式的交付,持續地證明與溝通這些價值,可以讓後續的重構之路更加平坦。

  2. 變更與意外

    雖說不改變,不見得沒有傷害,然而改變,很難不產生意外。揭露服務上線與變更時的可能風險、建立對應的監控與告警管理方式、災害復原(更好是能透過自動回滾,在短時間恢復)、與協調功能調整等,讓利害相關人了解狀況,並且有能力承受這些意外與變更。利害相關人不僅僅指的是管理階層,還必須考量業務單位、客服單位等其他相關人員。為了能夠更好的獲取相關人員的承諾,不妨為不同類型的相關人員設計適合的溝通方式,以便提升應變能力。

後記

重構主要導因於過往遺留的技術債務,原因可能是當時技術的內外部缺乏,也可能是資源缺乏。去除技術債或許令人高興,但遺憾的是技術債是個難以降至0的負向財產,因此重點並非打消全部債務,更多是不要發生資不抵債。從需求著手、從價值著手不僅僅是讓做的事情有意義,也能讓事情能夠順利展開,產生更好的結果。


參考資源

1. Photo by Brett Jordan from Unsplash