當了15年IT民工,待過幾家公司,做過不少項目,捅過一些簍子,也掉進過好多個坑,今天與大家分享一些對于技術債的看法。
大家都知道,我呢,是一個“長情”的人——不知道的話可以用這個關鍵詞加上我的名字搜索一下……。
也就是在一個公司待的年頭會長一些,也就有機會用更長的時間視角看待一些系統(tǒng)、項目的發(fā)展變化。
對于一些技術債務的產(chǎn)生和影響,以及后續(xù)的清償就有更多的切身體會,最近也比較關注,正好跟大家交流交流。
第一部分:技術債是如何形成的
技術債務是由Ward Cunningham在1992年創(chuàng)造的一個比喻,被定義為當我們有意或無意地做了錯誤的或不理想的技術決策所累積的債務。
這里有兩個關鍵詞,比喻和技術決策,還有兩個詞不那么關鍵,但也不能忽視,有意和無意。
我非常喜歡這個比喻,因為從技術管理角度,技術債務面對的也是各種成本和風險的問題,特別直截了當。
既然是比喻,總有不是太一致的地方,這是我們需要注意的,不能真的就當成欠錢那么簡單,這一點我們后面會提到。
最上面這張圖比較直觀的體現(xiàn)了技術債的一種定義,是負面的,消極的,不可見的。
IT領域的理念大師Martin Fowler對技術債也進行過思考和分類,但過多的引申概念可能會干擾思維,在這里就不說了,大家感興趣可以去看。
之所以說這個比喻非常好非常妙非常呱呱叫呢,是因為技術已經(jīng)成為許多企業(yè)的核心資產(chǎn)。
尤其對于一些互聯(lián)網(wǎng)公司,或者電信公司、金融企業(yè)、稅務部門(老三樣),業(yè)務運行重度依賴IT系統(tǒng)。
對于這樣信息化程度很高或者說IT系統(tǒng)就是業(yè)務生產(chǎn)服務系統(tǒng)的組織來說,線上的系統(tǒng)、代碼庫里的源碼、數(shù)據(jù)庫里的數(shù)據(jù)、甚至包括技術人員,才是最重的資產(chǎn)。
很多互聯(lián)網(wǎng)創(chuàng)業(yè)公司,列出預算,技術人員的薪酬才是最大的開銷,又偏偏是不能省的(能省早砍了),再輕的公司都得付出這個成本。
而一個企業(yè)運轉起來,積累的數(shù)據(jù)(包括用戶數(shù)據(jù)),沉淀的代碼和文檔,不斷升級的功能,熟悉業(yè)務的技術人員,這些都是業(yè)務更好發(fā)展的基礎。
這樣的公司,本就是運行在IT系統(tǒng)之上,一旦核心系統(tǒng)掛了,數(shù)據(jù)丟了,業(yè)務立刻停擺,直接帶來損失。
所以說技術部門已經(jīng)不是支持部門、成本中心,是需要投資帶來收益的生產(chǎn)部門。
既然技術是資產(chǎn),那就不僅僅是正資產(chǎn),還會有負資產(chǎn),也就是技術債。
簡單說,技術債就是那些該做但是沒做的,或者說做錯了的事兒。
有些債務隨著時間的推移,還會產(chǎn)生利息,而且可能衍生更多的債務。
正確的標準是什么呢?就是在對應的發(fā)展階段需要做的一些事情,技術體系也有發(fā)展規(guī)律,也需要建設周期。
比如一個網(wǎng)站或者Web應用從小到大發(fā)展起來,技術的路線圖大體上是一定的,在對的時候做了對的決策,自然事半功倍,否則就是事倍功半。
大家對軟件工程理論都有了解,都知道這么一句話:軟件錯誤發(fā)現(xiàn)的越早改正的成本越低。
所以呢,我們就看看技術債都會怎么產(chǎn)生,這里會泛化一些。
比如:
1.臨時方案,湊合著用,沒人再關注優(yōu)化改進。這方面有人會說這是MVP。
2.技術體系本身的信息化建設落后,不重視基礎平臺建設。
3.缺乏基本的文檔和規(guī)范,導致信息缺失和失控。
4.過度設計也會引入債務。
5.技術選型未跟上行業(yè)發(fā)展潮流,未享受到技術紅利,陷入競爭劣勢。
6.開發(fā)代碼貼膏藥,不寫注釋,不講究結構設計,只為實現(xiàn)需求功能,導致代碼腐化。
7.有缺陷的設計和代碼。
8.忽視數(shù)據(jù)收集和歷史數(shù)據(jù)沉淀。
9.網(wǎng)絡安全工作不到位
10.長期依賴人工進行功能測試
還有很多很多,各個層面的原因導致的債務。
第二部分:技術債有怎樣的風險,如何看待技術債?
如上所述,有些技術債是我們明確知道風險的決策,因為資源、時間之類的限制,進行了取舍,舍魚而取熊掌者也。
還有一些債務是無意中造成的,我們自己都不知道,充滿了不確定性。
這些債務一旦產(chǎn)生,就會衍生一系列問題,甚至多重疊加,出來混,總是要還的。
尤其是互聯(lián)網(wǎng)公司,系統(tǒng)外部環(huán)境更為復雜,更易引爆問題。
長期欠債的最大風險是隱性成本增加,欠債是為了節(jié)省成本,一直不還會導致其他成本上升,相當于是利息。
比如一些基礎的、底層的服務沒有做好,導致上層的應用必須考慮更多的邏輯,難以簡化。
債務就像冰山一樣,沉在水面下,容易被忽視,積累到一定程度會爆發(fā)債務危機。
這就像滾雪球,滾到后來就不知道最初的小雪球是什么樣子了,變成了無處下手的大雪球。
直接的風險多數(shù)是指觸發(fā)故障導致?lián)p失。
比如提倡敏捷,放松質量要求,測試不到位,常在河邊走哪有不濕鞋。
比如設計時未考慮面對更高業(yè)務峰值的場景,架構難以橫向擴容。
比如生產(chǎn)環(huán)境未作隔離,導致測試環(huán)境應用干擾了正常業(yè)務。
比如測試環(huán)境與生產(chǎn)環(huán)境不一致,驗證結果不具備參考性。
比如N年前不知道誰寫的代碼里有一個特殊判斷,其實正常情況下是不必要的,湊巧趕上了,引發(fā)了意想不到的結果。
技術債的后果,有人整理如下,應該主要指傳統(tǒng)的IT服務企業(yè),可作為參考:
1.爆發(fā)點不可預期
2.交付時間延長
3.缺陷數(shù)量可觀
4.開發(fā)和支持成本上升
5.產(chǎn)品萎縮
6.可預測性降低
7.表現(xiàn)越來越差
8.挫敗感四處彌漫
9.客戶滿意度降低
我很不喜歡欠錢,大家都知道談錢容易傷感情,而談感情呢,容易傷錢。
所以我也很不喜歡技術債,總覺得技術債不是個好東西,看著礙眼,如鯁在喉。
但我自己也因為各方面原因,欠下過不少的債,有的一直沒還上。
尤其是很多時候我們只是接手別人的工作,同時就要接手現(xiàn)存的債務。
完全不欠債只是一種理想狀態(tài),欠債才是常態(tài)。
欠債太多,會導致惡性循環(huán),如果是規(guī)模較小的系統(tǒng)和組織,還比較容易扭轉,否則一旦形成不良趨勢,要剎住勢頭,再往回拽就很難很難了,需要極大的勇氣、毅力和方法。
第三部分:技術債的清償方式
技術債只是一種比喻,與財務領域的債務還是有區(qū)別的。
比如這種債務的形式很多,又沒有欠條,觸發(fā)的時間點并沒有明確的期限,更沒有債權人,不能指望寬宏大量免除債務。
多數(shù)人在進行技術決策之后就會認為已經(jīng)解決問題,造成的債務摸不著看不見很快就拋之腦后,感覺心情愉快,空氣清新。
而債務是會被繼承的,人在做,天在看,不是你不知道,忘了就不存在了。
這些隱藏的債務,就是一顆顆不定時的炸彈,一旦碰上,都是意外驚嚇,手忙腳亂,灰頭土臉。
債務爆發(fā)需要償還,會打亂當前的工作計劃,而且要付出更多的成本,有時候光弄清楚到底什么問題就要很長時間。
好在亡羊補牢,為時未晚,早發(fā)現(xiàn)早解決,事情多半是繞不過去的。
前人挖坑,后人填坑,碰上了別說倒霉,很多人也是在解決前人留下的債務危機中迅速成長起來的。
一般來說,就事論事解決就好,如果積累太多,千頭萬緒一團亂麻,那就快刀一斬,推倒重來,重構。
重構看起來像是東山再起,沒有在原系統(tǒng)上修修補補,但一樣是償還了債務的,而且還可能引入新的債務。
在有些情況下債務的確不需要償還,或者用很少的代價就能解決。
1.債務產(chǎn)生的問題在可容忍范圍內(nèi),處理債務的收益不高。
2.因業(yè)務發(fā)展變化,產(chǎn)品生命周期結束,最終下線。
3.新技術的出現(xiàn),硬件性能的提升,可以通過另外的方式緩解債務。
比如曾經(jīng)有這樣的例子,應用性能不行,需要優(yōu)化,還在分析梳理,突然聽說別的系統(tǒng)替換下來一臺很牛的服務器,正好挪過來一上,速度飛快,問題就不再是問題了,DB換SSD也差不多。
<賣瓜時間>
比如搞SOA服務治理,Java之外還有其他語言,想HTTP調用,后來發(fā)現(xiàn)了DubboX。
比如定時任務散布在服務器上,缺乏統(tǒng)一管理,還到處都是單點隱患,發(fā)現(xiàn)了Elastic-job。
比如MySQL數(shù)據(jù)量大了,直接拆庫,在應用里把分庫邏輯寫死,業(yè)務迎來快速發(fā)展期怎么辦?發(fā)現(xiàn)了Sharding-JDBC。
第四部分:如何避免技術債務危機
技術債的發(fā)展需要時間,又容易被忽視,成為房間里的大象,如果積累過多,在感知上會集中式爆發(fā)。
技術債的集中爆發(fā)嚴重情況下一樣會導致體系崩潰,爛攤子不可收拾,這種時候重構跟破產(chǎn)重組差不多,甚至可能導致企業(yè)垮掉。
一個合格的技術管理者,要保持對技術債務的敏感度,更要適時的調配資源,解決部分技術債務,避免失控。
但也不需要過于敏感,處處小心,防微杜漸,或者優(yōu)柔寡斷,有的時候不做決策一樣是一種決策行為,會導致債務。
每個系統(tǒng)都有結束歷史使命的一刻,但不應該因為技術債務而垮掉,要避免爆發(fā)危機,就要對技術債務進行管理,控制在可接受水平。
最簡單有效的方式,就是維護一個債務列表,類似于待完成任務列表。
一旦發(fā)現(xiàn)債務產(chǎn)生,盡快登記在案,人的記性總是靠不住的。
有了這樣一個列表,管理起來方便很多,可以公開,既可以區(qū)分重要程度和優(yōu)先級,還可以記錄一些關聯(lián)關系。
Uber的工程主管Raffi Krikorian在《架構之重構的12條軍規(guī)》也專門列出了一條“管理好技術債務”,建議列出清單。
有的人建議給每個債務定義價格和利率,并進行計算,雖然更直觀,但感覺比較難以估量實際價值,最終體現(xiàn)的還是重視程度。
如果考慮全面,可以一石N鳥,串起來一次性解決多項債務,甚至還能帶來額外的收益,或者在業(yè)務需求實現(xiàn)中連消帶打清理債務。
技術體系是為業(yè)務服務的,但不能僅憑業(yè)務需求驅動,需要分配一定比例的資源還債、優(yōu)化、創(chuàng)新。
以上說法主要是被動式的,主動的預防也很重要,而且預防是多方面的。
1.招聘能力符合要求,踏實做事的人才,維持團隊穩(wěn)定,避免發(fā)生斷檔。
2.制定完善的項目流程規(guī)范,對設計進行評審,提高整體的質量意識。
3.對代碼進行Review。
4.不同領域的技術應用通過專家小組方式進行管理。
5.對項目和故障進行復盤,及時發(fā)現(xiàn)問題。
6.建立完善的監(jiān)控系統(tǒng),對系統(tǒng)運行數(shù)據(jù)進行分析,關注趨勢和異常。
第五部分:技術宅怎樣與技術債共度一生
作為一個技術宅,我常常說自己是IT民工,這個工字呢,不管是叫工人還是攻城獅,都是跟工程學有關,對,我是個工科生。
所謂工程,是要落地實現(xiàn)的,有生命周期,有邊界和局限性,有各種不足和缺陷的。
就像在醫(yī)生眼中,每個人身上都有一些小毛病,沒有一個完全健康的人。
沒有哪個系統(tǒng)會是理想中的樣子,技術債是必然存在的。
這樣來看,每個技術宅都會遇上技術債。
總會有自己接手的第一筆債,還的第一筆債,欠下的第一筆債。
于是開始與技術債相愛相殺的職業(yè)生涯,接下來面對更多的債。
俗話說得好,虱子多了不癢,債多了不愁,債多不壓身。
但這樣的心態(tài)不免過于良好,甚至有些不負責任。
越大的系統(tǒng),其中包含的技術債務越多,越高的技術管理者越要重視債務,規(guī)避“系統(tǒng)性風險”。
什么是系統(tǒng)性風險?08年的次貸危機,很多赫赫有名金融機構就翻了船,越大的系統(tǒng),出現(xiàn)問題的代價越高,風險越需要重視。
存在即合理,技術債也有兩面性,就如同房貸、車貸,給我們在某些方面的收益。
因此正視技術債,有意識的管理、使用好技術債,是技術管理者必備的技能,必經(jīng)的修煉。
你見,或者不見
債就在那里
今生,今世
不棄,不離