為啥項目做到最后都成為了“屎山”,代碼改不動


開頭先來個小故事:張三是一個程序員,在金九銀十的季節去了一家新公司就職。新的公司看起來前景不錯,做的產品也屬於行業前沿,張三發誓自己要在此一展鴻圖,用自己精湛的開發技術為公司的上市添磚加瓦。

張三就職的第一天,公司就開放了代碼的權限,他熟悉起公司的核心項目。結果卻驚呆了,張三發現公司的項目就像是一個垃圾場,各種代碼堆成山,而他要做的事情,就是去維護這些老項目,在那一刻,張三內心的幻想瞬間破滅。

但在維護了一段時間項目之后,事情出現了轉機。有一天,新項目下來,老板任命張三為負責人,他內心狂喜,終於可以證明自己了。

"我一定要讓代碼顯得優雅,跟爛代碼說再見。"

剛開始,張三用了各種設計模式,瘋狂抽象業務,越做越有勁,感覺一身的才學終於有了展示的機會。但項目是多人合作的,隨着時間的流逝,和項目的不斷迭代,很多新人不再按照預定的規范來開發代碼。

為了方便,微服務如雨后春筍般一個個往外面冒,開發人員在代碼里填充了一個又一個if語句。於是,張三開始手動地限制那些不符合規范的代碼提交。可是項目時間的壓力越來越大,張三最終迫於交付壓力又放開了限制。雖然項目順利的交付完成,但是奇怪的代碼卻永久地留在了項目中。

慢慢地,原始精美的設計開始變得越來越臃腫,邏輯變得復雜無比。沒有人敢去重構,也不可能重構了。終於,張三實在無法忍受,辭職去了一家新公司就職,新的公司看起來前景不錯,做的內容也是行業前沿的產品,張三再次發誓自己要在新公司一展鴻圖,用自己精湛的開發技術為公司的上市添磚加瓦...

這樣的故事在互聯網行業內一遍一遍地上演,似乎任何項目隨着時間演進,一個個補丁打到最后都會變成“屎山型”項目,充斥着各種歷史遺留問題,新功能開發越來越慢,最終無法演進走向項目的終結。有些互聯網公司會為延長項目的生命周期,在某個節點聘請資深的軟件架構師,他們往往熟讀《重構》,用各種各樣的技術手段去延緩這個過程。

最近我在網上沖浪的時候發現了一個叫做"產品架構"的概念,再結合曾經做過的一個個項目,突然有了些許感悟。

研發人員習慣用技術解決問題,但問題的解法是多樣的,有時候只需換一個度切入。當然,無論用什么方法,歸根到底,都是人的問題,這里只是提供一種思路,僅供參考。

產品架構是啥

像軟件架構一樣,產品設計也是有架構的。

在做項目的時候,我們覺得從技術上,所有的問題都能得到解決,但是整個項目卻在不知不覺間一步步的走向“屎山型”項目。按照研發的思維,問題的根源是抽象還不夠,技術水平不行,需要更強大的架構師來重構。

聘請了資深的軟件架構師后,一開始項目似乎變得好了一些,但最終結果並沒有發生改變,只是延緩了而已,到了某個階段也只能拋棄,重新開始。

復盤后會發現,我們的主要精力都在解決技術上的問題,而忽略了產品層面。按照網上的一種說法,產品架構就是在充分理解產品用戶需求基礎上對產品數據流轉的邏輯梳理。

而我對產品架構的理解是從"理念世界"開始的。編程是用計算機能夠理解的語言來描述現實事物,計算機能夠理解的語言是什么?是邏輯。在編程的時候,研發人員需要在腦海中構思出事件的全貌,並且用邏輯的語言將它描述出來。

在西方的哲學里面有一個"理念世界"的說法,大概意思是人們做的任何事情,都是在腦海中預先構建出事物的本體,再到現實中對預先構建的內容進行模仿。這與我們編程的過程很相似,那么產品是否也遵循這個過程?

回想起以前做項目時的思考方式,發現確實如此,我們或多或少都需要在腦海中構建出產品的運行軌跡。但是在做項目的時候,作為研發的我們都在想如何用技術解決問題,卻忽略了更重要的東西,任何產品都是為了解決客戶的問題而存在,解決客戶的問題是根本,無論用什么手段......

 

如何設計產品架構

在設計之前,先解決人的問題,什么樣的人適合做產品架構?

產品架構就是在充分理解產品用戶需求基礎上對產品數據流轉的邏輯梳理。

所以這個人需要具備以下素質:

  • 能夠調研並理解用戶需求的能力
  • 能夠知道產品的核心價值
  • 能夠理解產品運行原理
  • 面向對象設計思維

有了這些素質,就可以開始構建"理念世界"了。

構建理念世界

構建"理念世界"其實就是將現實中將要發生的事情,用面向對象設計思維將事情轉換成純粹的邏輯描述,這個過程叫抽象。

舉個例子,如果我們需要做一個流量治理類型的產品,抽象過程大概是這樣的:流量治理基本分為2個大的內容,流量監控和流量管理,這是核心價值。

而傳統的流量治理工具基本都是采用SDK的方式實現,它們普遍具有以下的問題:

  • 侵入性強
  • 治理功能不全
  • 內容多、門檻高
  • 中間件演變困難
  • 版本碎片化嚴重
  • 升級成本高

如果能解決此類型的問題,將會使得服務網格在流量治理解決方案上會優於SDK的方式,這是比較優勢。

有了上面的分析,可以得出:如果希望產品可以快速升級且侵入性弱,勢必不能與客戶的代碼進行強綁定,需要一種與語言無關,又能夠做到流量監控,流量管理的手段,只能去操作系統上面找。

如果能操縱操作系統上的某些功能,使得流量在進入服務之前,先進入編寫的程序中,就做到了語言無關。

思路大概是這樣:一個請求進來,先被操作系統轉發到編寫的程序中,然后我們自己編寫的程序會將數據上報到某個東西保存起來,最后程序轉發到真正的服務中,流量監控就做完了。同時,還需要一個用於存儲上報數據的東西,它需要具備持久化的能力。

在這個流程當中,使用了一種設計模式,叫sidecar模式,就用sidecar稱呼我們自己編寫的程序好了,存儲的那個就叫數據庫。

為啥項目做到最后都成為了“屎山”

 

接下來推導一下流量控制的邏輯,要做到流量控制,需要用到sidecar,畢竟流量已經被操作系統轉發到了sidecar上面,我們可以做過處理之后再轉發到真正的服務當中。那么就需要一個另外的東西,它來告訴sidecar要怎么對流量進行處理,畢竟每個sidecar需要處理的東西是不同的,而且策略內容需要持久化,不然找不到與sidecar的對應關系,這個東西叫做控制端。

所以流程大概變成:控制端配置流量控制策略,控制端將策略下發到sidecar上,一個流量請求過來,被操縱系統轉發到sidecar,sidecar先上報流量數據到數據庫,然后根據流量策略對流量進行處理,最后將請求轉發到真正的服務中。

為啥項目做到最后都成為了“屎山”

 

在完全理想的狀態下,通過這樣一個流程,基本實現了流量治理的核心能力,並且這個流程相比SDK的方式更具有優勢,這就是所謂"理念世界"的構建過程,純粹的邏輯描述。

驗證理念世界

"理念世界"是否正確的唯一衡量標准是它是否完全正確的描述了現實,就像面向對象思維里面的類和對象的關系,"理念世界"是對現實的抽象。

要想知道抽象的好不好,有一個非常有效的辦法。隨便找幾個人,把你的邏輯說一遍,如果表述的過程是順暢的,對方能夠理解並且沒有感覺到邏輯上的遺漏,這個抽象就是比較好的。

在做項目的時候,可以把這個過程盡量的描述給不同崗位的人,一邊加深團隊成員對產品的理解,一邊又通過不斷的表述來完善這個流程沒有考慮完善的內容。

如何落地

當"理念世界"被建立,就需要在現實中對它進行模仿,在軟件工程學當中,這一步就要開始脫離設計,到實操的階段。一般項目分2類,一類是從零開始,一類是存量項目。

從零開始的項目

從零開始的項目在動手之前,一般會面臨2個問題,從哪開始?要模仿到什么程度?

為啥項目做到最后都成為了“屎山”

 

通過流程可以發現以下是一切的基石。

1.操縱操作系統上的某些功能,使得流量在進入服務之前,先進入我們編寫的sidecar中

2.sidecar

3.數據庫

所以在沒有外部特殊情況干擾的時候流量監控功能肯定要優先於流量控制功能做,這是從哪開始。

至於做到什么程度主要依托於時間,人員的關系,看實際情況把握。但無論做多少,只要方向是對的,對整個 產品的迭代都是具有正向的意義。

通過這張圖,服務划分變得很清楚,在交給研發時,每個服務的邊界也有明確的規定。就算研發人員出現新入職或者水平良莠不齊的現象,在這個框架內所能造成的破壞力也有限,不會對整個產品造成結構性的問題,在未來的某個時候只需要找一個足夠強的研發重新寫一遍,問題就都解決了。

存量項目

存量項目的落地就十分的復雜,歷史遺留害人不淺......

大的思路應該是先用"抽象"映照現實,看看到底現在的代碼是否完全符合"抽象"的"流程",先搞清楚現狀再想辦法修枝剪葉。

如果有新的需求到來時,還是要先抽象,任何正當的需求都是符合邏輯的,如果抽象出來不符合邏輯,那肯定是需求挖掘的不夠,不能盲目的加代碼。

還是那個例子,如果需要添加一個對sidecar的監控,那流程就會變成這樣。

為啥項目做到最后都成為了“屎山”

 

但是監控單獨拎出來是否有必要?如果沒有必要的話流程可以變成這樣。

為啥項目做到最后都成為了“屎山”

 

這2種形態沒有優劣之分,可以結合具體情況做選擇。

總結

如果有了解到服務網格領域的朋友應該很早就發現,上訴說的例子就是一個弱雞版Istio的誕生。

我嘗試着從需求出發,純粹的邏輯推導Istio的架構。很多有名的開源項目為什么歷經這么多年,反而越來越精煉,這里面一定有值得探討的地方。

本文只是提供一種解決問題的方法,解決問題的核心還得看人,一群大佬,無論用什么方法做出來的東西都精美而優雅。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM