技術選型的藝術

程式碼灣發表於2018-05-03

什麼是技術選型

技術選型對於廣大程式設計師,特別是網際網路公司的技術負責人或者架構師來說,一定不陌生。小到日常開發中的一個工具庫的選擇,大到整個系統語言、架構層面的選擇,都是技術選型的範圍。今天我們就簡單聊聊技術選型。

一般而已,我們會碰到的技術選型,可以分為以下幾類:

  • 基礎設施選型:雲平臺或IDC、程式語言、資料庫等。
  • 框架和庫的選型:前後端的開發框架、核心類庫等。
  • 中介軟體選型:負載平衡、訊息中介軟體、快取中介軟體等。
  • 第三方服務選擇:第三方的推送、簡訊等。

實際上,我們常常面臨的不是單個技術的選型,而是對於一個專案所涉及的一整套的技術、方案、規範或者產品的選型。這就需要我們更仔細的去權衡各種技術、各種組合的利弊,作出取捨。

技術選型,其實本質上就是一種架構決策。《系統架構》這本書裡將架構決策總結成了六種模式,包括選項、篩選、指派、分割槽、排列和連線。而技術選型明顯屬於其中的選項(Decision-Option)模式,也即每個決策都是一套離散選項,從中選擇一個合適的。

影響技術選型的因素

專案因素

首先考慮的是專案。

我們要明確專案本身的性質,包括專案的規模、重要程度、時間要求等等。如果是一個小規模的實驗性專案,那麼嘗試一些新技術也未嘗不可。如果時間要求非常緊,那可以考慮基於開源或商用的程式修改。淘寶當年上線時候,就是購買了一個商用程式後修改的。另外,專案的成本和預算也是必須要考慮的。如果預算足夠,我們也可以考慮購買商用程式或者第三方服務。

專案的需求也會影響甚至限制技術的選型。特別要注意的是那些非功能性的需求,例如對併發性、實時性、可用性、資料一致性、安全性等方面的需求,往往對技術方案和選型有很大影響。例如支付相關的應用,對資料的一致性有非常高的要求,那核心的支付資料的儲存,就會傾向選擇 Oracle、PostgreSQL 這種強一致性的資料庫,而不會去選 MongoDB(雖然據說馬上也要支援事務了)。

團隊因素

其次要考慮的是團隊,也就是說人的因素。

技術選型一定要考慮當前團隊人員的技術組成。對於一些比較基礎的技術的選型,比如語言和框架、資料庫等等,往往最合適的選擇就是團隊最熟悉的技術。如果打算選擇不同的技術的話,那就要考慮下團隊是否有人能夠 Hold 住了。另一個必須要考慮的是招聘,如果使用的是比較小眾的技術,那麼當需要擴充團隊的時候,招聘人員會比較困難。我們杏仁在這方面就取了一個巧,最開始我們用的是基於 JVM 的 Scala 語言,但是我們招聘的時候,都是打的 Java 工程師的幌子。

團隊的發展時期對於技術選型也會有一定影響。對於早期團隊,大多數員工都是喜歡創新、願意承擔風險,那麼可以選擇一些相對較新、有挑戰的技術;團隊發展到一定階段,那就要開始考慮團隊效率、開發規範等因素,此時往往會選擇一些比較大眾的、經過驗證的技術。

我加入現在的公司時,我們正好開始轉型。原有的產品是基於 Web 的網站,我們打算開發一個移動 APP。我們原先後端應用使用的是 Scala 語言和 Play 框架,當時面臨的一個問題是,新的產品後端應該選擇什麼技術?雖然也考慮過 Java,但因為時間很緊,我們還是選擇了團隊最熟悉的 Scala。但後面我們開始服務化的時候,就選擇了 Java。

還有一點就是,雖然技術選型需要考慮團隊人員的喜好,但千萬不要因為某幾個人的個人喜好,來決定技術的選型。還是通過細緻的分析和實驗來進行選型。而決策者也需要看的更長遠一些,推動團隊技術向前發展。

技術因素

技術選型當然也必須考慮技術因素,例如技術特性(易用性、可維護性、可擴充套件性、效能等)、技術成熟度、社群活躍度、架構匹配和演化等等。

技術特性往往是大家都會去關注的,相信不必多說。但是注意不要只是瀏覽網上看到的各種分析,對於重要的特性,還是需要去親自實驗一下或者做一些測試,有第一手的感覺。另外,這些特性往往不可兼得,所以我們需要對照專案因素和團隊因素來進行取捨。

技術的發展有其內在趨勢,Gartner 每年都會釋出一個 Hyper Cycle,標記各種技術的發展階段;另外一個很好的參考是 ThoughtWorks 的技術雷達。我們可以根據專案、團隊等因素去選擇不同成熟度的技術和產品。但是對於核心專案,最好還是選擇足夠成熟的技術,切忌盲目追求新技術。

對於比較重要的應用,我們一般會選擇比較大眾的技術,因為使用的人多了,也從某種程度上說明這個產品是比較優秀的,並且招聘也會更容易些。這方面可以參考的有 Github 的 star 數、Google Trends、百度指數等等。社群活躍度也是必須要考慮的因素,你一定不會想用一個沒有人維護,提了問題也沒人回覆的技術產品吧。

最後還需要考慮技術產品和當前架構的匹配程度。一個團隊的技術棧太過散亂,對開發和運維會是很大的壓力,甚至影響系統的穩定性。例如我們當前的資料庫使用的是 MySQL,而一個技術產品如果要求必須引入 MongoDB,那我一定會多想一下,我們多維護一個 MongDB 是不是值得。另外,如果大家對自己架構的演化有一定規劃,那也要考慮引入的新的技術產品和未來的架構是否能夠匹配。

其他因素

最後,可能還會有一些額外的因素要考慮。比如許可協議的問題,前段時間鬧得沸沸揚揚的 React Native 許可協議事件,相信大家記憶猶新。還有一些公司,可能對於使用第三方的程式或者服務,有一些原則甚至規範,那也一定要注意參考。另外,在稍大一些的公司裡可能還會涉及一些派系之爭,這裡就不多說了。

如何進行技術選型

我們上面已經列出了很多技術選型需要考慮的因素,那麼到底如何進行技術選型呢?大致上可以分為以下幾個步驟:

  1. 首先要明確選型的需求和目的,最好能列出必須要考慮的各種因素以及評判標準。
  2. 然後就可以開始尋找候選技術或產品了。這時範圍可以儘量廣一些,蒐集儘可能多的候選技術和產品。
  3. 其次就可以進行初步篩選。把一些由於各種限制無法選擇的、或者明顯不可能的技術或產品排除,篩選出 3 個左右備選方案。
  4. 再然後就要做一些詳細的調查和分析了。可以列一個表格,把備選方案、以及需要考慮的因素放到表格的橫向和縱向中去,一個個進行評估的分析。此時可能會需要做一些小 Demo 驗證可行性,或者做一些效能測試、壓力測試等等。必要的話可以在表格裡給每一個因素打分。
  5. 最後,對分析結果進行評審,作出最後決定。

技術選型分析表,每一格里可以有具體的打分,也可以有優勢劣勢的評價。

候選A 候選B 候選C
技術成熟度
架構一致性

當然,小的不太重要的技術選型也不一定要這麼麻煩,而重要的技術選型則可能要反覆各個步驟多次。

技術選型的幾個注意點

  • 一定要進行可行性分析,如果不太確定,做個 Demo 驗證一下。如果專案進行到一半,發現原來設想的某個方案不可行,那會是非常痛苦和浪費時間的事情。
  • 不要有思維定勢,習慣性的使用某些技術,比如服務化就用 Dubbo、快取就用 Redis,具體問題要具體分析。也不要趕時髦,在重要的專案上使用太新的不夠成熟的技術。
  • 隨著業務發展,很多架構需要不斷升級,所以一定要考慮未來如果要替換某項技術,是否會很麻煩。可以選擇符合一些標準的技術或產品,或者在應用中部署一個適配層,方便未來適配其他技術。
  • 架構應該儘可能統一,一個領域避免引入太多相同功能的技術產品。

總結

最後,大家其實會發現,技術選型既是一種科學、又是一種藝術,有時候並沒有對錯之分。最後面臨兩難選擇的時候,還是需要決策人拿出勇氣,拍板決定,堅定的去推進。

相關文章