轉載:http://techblog.ppdai.com/2018/03/26/20180326/
1、前言
技術選型是一個很熱門的話題,最近我看到本身的微信朋友圈有好幾篇關於技術選型的文章,讀者對這類主題的熱情很高。在技術組織內部,技術人員常常會面臨技術選型問題,有時候,技術選型還經常牽扯好幾波干係人,相互之間還會產生爭議,有的甚至還可能發展到派系鬥爭的地步。即使像我本身,已經有十幾年研發和架構經驗的老司機,無論是工做仍是業餘,有很大部分時間的思考都是深陷在A技術和B技術的利弊權衡之中,不能自拔。不管如何,技術選型說小了關乎項目和團隊成敗,說大了關乎企業業務的發展,不可小覷。前端
本文所表達的技術選型理念應該是具體技術無關的,可是因爲我我的的背景更偏向互聯網後端的研發和架構,因此本文的視角更偏向後端技術的選型。sql
2、軟件的本質複雜性
近年,雲計算、微服務、容器和DevOps等新技術和理念層出不窮,技術人員對各類新技術的追捧熱情也空前高漲,各類新技術微信討論羣也如雨後春筍般冒了出來。這是一個好現象,說明咱們的開發人員多了,技術環境也日趨成熟,有點百花齊放的感受。同時也讓我有一點擔心,我擔心的是純技術和工具論的擡頭,也就是太過專一技術,認爲技術能夠搞定一切,反而忽略了軟件研發的本質複雜性。回想當年,本身也曾是這樣的技術狂熱分子,EJB剛出來的時候,我爲EJB搖旗吶喊,Spring出來的時候,我也曾一度是該技術的死忠,簡單認爲這些技術是銀彈能夠幫助解決全部的複雜性問題。數據庫
1986年,人月神話的做者Brooks就提出,軟件的本質複雜性(Essential Complexity)存在於複雜的業務領域中(用技術的話講是業務領域建模複雜性),技術僅是輔助工具,它解決的問題是幫助將業務領域問題映射轉換成軟件實現,只解決次要複雜性(Accidental Complexity)。做者同時指出,因爲軟件本質的複雜性,真正的銀彈並不存在;也斷言在十年內,沒有任何一項技術或者方法可以使軟件工程的生產力提升一個數量級。30年前做者提出的論斷,今天依然閃爍智慧的光芒。人月神話已經出了40週年記念版了,堪稱軟件工程的聖經,建議全部從事軟工行業的朋友學習。除了業務和技術,我還想強調軟件的本質複雜性同時隱含在企業的人、組織、流程和管理中,不容忽視。編程
架構師只有深入理解軟件的本質複雜性,才能站在解決實際業務問題的角度,更好的作出技術選型,不然易陷入惟技術工具論的陷阱。後端
3、使用成熟的技術
大部分公司都是商業組織,不是科研機構或者純軟件研發機構。商業組織使用技術是爲了解決當下的業務問題,他們更應該使用成熟穩定的技術。微信
以下圖,技術的使用有明顯的生命週期,早期有創新者和早期使用者採用,我把這個階段稱爲試水趟坑期,也就是說這個階段技術不是很成熟穩定的,雖然嘗新者可能佔據必定的技術領先優點,可是他們經常須要以踩坑填坑做爲代價;若是這項技術通過早期驗證則會跨越鴻溝進入早期大衆階段,這個階段技術會逐漸走向成熟,處於上升期,坑逐漸被填平,技術被大衆所採納;以後技術緩慢通過末期大衆階段,最終走向滯後期,一直到生命週期的結束退出歷史舞臺。架構
技術選型的一大智慧是不要盲目追求新技術,老老實實採用成熟穩定的技術,讓那些喜歡追新的人去踩坑😊,等這項技術跨越鴻溝,進入早期大衆階段,你再擇機投入,這樣最保險和高效。固然做爲技術人員,對新技術保持敏銳,提早預研是徹底OK的,可是投入生產的話仍是成熟穩定第一。app
4、少便是多
一項新技術既有學習成本,又有維護(定製、監控、管理和運維)成本,新技術引入很容易,學好用好運維好卻很難。一個不嚴格把控技術棧數量的公司,開發人員經常會各自爲政,隨意引入新技術,形成技術棧散亂,學習和維護成本高,技術棧知識沒法共享,技術體系沒法創建等問題,嚴重的會極大影響研發效率和業務規模化能力。框架
以我本人專一的後端基礎框架領域爲例,技術棧散亂還會直接影響系統穩定性,由於技術組件和工具太多,沒法統一埋點和創建完善的監控體系。當業務量發展到必定規模,技術棧散亂還會給系統擴容跨機房遷移等帶來巨大障礙。運維
在一些成熟的互聯網公司,好比國內的阿里,國外的Netflix和eBay等公司,這些公司雖然財力和資源豐富,可是他們的核心技術棧(好比主流開發語言,框架和數據存儲等)的數量一樣是受到嚴格把控的。
新技術引入的基本原則就是少便是多,能不引入新技術儘可能不要引入新技術,確實須要引入的話,也要有相應的新技術引入管理流程(通常由公司的技術或者架構委員會制定和把控)。
5、技術的先決條件
技術引入經常是有一些先決條件的,比方說最近比較熱的微服務架構,按照馬丁福勒的說法,微服務有以下先決條件:
- 快速的環境提供能力(Provisioning)能力(一般指IAAS層能力),
- 基本的監控能力
- 快速的發佈能力
- 初步的DevOps文化
馬丁特別指出「你必須長足夠高才能考慮微服務」,在這些先決條件沒有知足以前,直接推行微服務會面臨巨大落地挑戰。
一樣,容器技術的引入對應用也是有要求的(參考[附錄18.1] ~ 12 Factor App),而DevOps研發模式的引入不只對基礎技術和架構,研發人員技能,甚至組織架構和企業文化都是有很高要求的,在沒有知足先決條件前,這些新技術或研發模式都會面臨巨大的落地挑戰。
做爲管理者或者架構師,在引入一項新技術以前,要充分調研瞭解新技術的先決條件,不能盲目引入。對於確實須要引入可是目前還不知足先決條件的,須要作好階段性規劃,先打好基礎,再適時引入新技術。
6、來自大公司的技術
大公司採用的技術,未必適合中小公司。大公司有足夠的資源、人力和時間,能夠投入一些前沿和重量級的技術(在BAT級別公司,爲重量級技術投入幾十甚至百人以上的研發團隊是很正常的事),可是中小公司資源有限,不能盲目跟風,應該選擇和本身發展階段相適應的技術,不然不只不能幫助業務發展,反而會給業務發展帶來阻礙。
7、技術的文化特性
技術經常帶有文化特性的,在國外流行的技術,在國內未必流行。一個例子是如Scala這樣的函數式語言,Scala在國外互聯網公司是有必定流行度的(Twitter、Linkedin等),國內雖然有很多簇擁者,可是始終只是小衆,沒法流行,究其緣由,國外不少大學教授的第一門編程語言是採用函數式語言的(例如美國Berkeley大學的CS61A是基於Scheme函數式語言),國內大學幾乎清一色採用C/C++/Java等命令式語言做爲第一門編程語言。也就是說函數式語言在國外是有文化基礎的,因此容易流行,國內沒有這樣的文化基礎,因此難以流行。
咱們在選型的時候,儘可能採用在國內有文化基礎,已經落地開花的技術,盲目追求國外新技術有可能文化不適應反而難於落地。
一樣的,在A公司流行的技術,在B公司也未必流行。比方說BAT三家公司所採用和後面演化出來的技術棧就明顯不一樣,這一樣和三家公司不一樣的業務領域和文化基因有關係。咱們在作技術選型的時候,也要考慮公司的文化特性,如業務模式、已有技術生態和開發人員技能等現實狀況。
8、開源仍是第三方軟件提供商的技術
互聯網時代,傳統的企業軟件供應商開始明顯地走下坡路,企業愈來愈多的採用開源技術來開發他們的業務系統,開源軟件具備以下優點:
- 成本,商業軟件通常有昂貴的license費用;
- 避免供應商綁定(vendor lockin);
- 靈活的定製能力,現代企業須要靈活的軟件定製能力以應對快速變化的用戶需求,商業閉源軟件經常缺少這種能力;
- 社區和生態,投資具備良好社區和生態的開源技術是企業技術選型的最佳實踐。
即便是開源軟件,這裏面有一個很重要的閉環問題。有些開源軟件是一線互聯網公司成功落地後再開源出來的,好比阿里的dubbo,點評的CAT,這些公司自己有場景,內部大量使用,也就是說內部已經造成反饋閉環,開源出來和社區又造成了一個更大的反饋閉環。有一些第三方軟件供應商提供的開源軟件,其實他們自己是沒有業務場景的(或者場景很是有限),主要靠社區使用後才能造成反饋閉環,對於這類開源軟件的使用須要謹慎,若是選擇的話,可能須要一塊兒幫忙踩坑造成社區反饋閉環。
9、使用能掌控的技術
技術和武器同樣,並非說越先進越好。就像航空母艦和F117這樣的尖端武器,確實很是厲害,可是掌握和部署運維這些武器的成本很是之高,若是你的團隊沒有足夠的能力運維和掌控這樣的武器,那麼這些武器擺在家裏充其量只能是擺設,不能造成戰鬥力,有時甚至還會拖累業務。
在大數據領域重量級武器尤爲多(Hadoop, HBase, Spark, Storm…),不少產品既消耗機器資源,部署和運維也很是複雜,若是某種重量級武器被應用在關鍵業務上,一旦出問題,團隊能不能hold住是要重點考慮的,不然可能會死得很難看。架構師須要根據業務階段規模,團隊規模和技能水平,綜合評估後再考慮引入,若是團隊能力還不足以掌控某種重量級技術,則能夠先從輕量級技術開始。
10、劍要交給懂得揮舞它的人
同一種技術,不一樣的人使用,可能會得出徹底相反的結論。好比Cassandra這種NoSql分佈式數據庫,在Netflix有比較成功的應用,Netflix從2010開始將系統遷移到AWS雲中,並開始將大部分業務數據從傳統Oracle數據庫遷移到Cassandra上,Netflix的前架構總監Adrian Cockcroft把他們技術升級的一大成功功勞歸結爲採用了Cassandra這種自然支持跨數據中心的分佈式數據庫。可是,在2012年時候,Digg在網站改版升級過程當中也試圖將傳統Mysql數據庫遷移到Cassandra Nosql數據庫,結果致使Digg網站問題頻發,最後技術副總裁John Quinn主動捲鋪蓋走人。過後,有人將問題歸結爲Cassandra,這就是著名的Digg使用Cassandra遭遇滑鐵盧事件。有人在Quora上發帖提問「Is Cassandra to blame for Digg v4’s technical failures?」[附錄18.2],回帖中有知情人士出來澄清:把Digg網站升級失敗歸結爲Cassandra徹底是轉移注意力(red herring),背後的真正緣由是工程管理和架構的問題(poor engineering management and architecture),簡單講就是人的問題。
我曾經在2013年左右在攜程框架部工做,當時有一個很重要的框架產品叫分佈式數據訪問層DAL,不少團隊都躍躍欲試要作,可是當時的CTO一直沒有正式啓動這個項目,理由是沒有合適的人。這個事情拖了有一年之久才找到合適的人,這個項目才啓動並逐步落地,如今已是攜程框架的關鍵基礎設施,承載攜程大部分數據庫訪問流量。
對於一些重量級的,處於業務關鍵鏈路上的產品,若是它重要但不緊急的話,必定要找到並交給能搞定它的人。把一個重要產品交給一個不合適的人,不只不能解決問題,後續還經常會製造問題。設想一下業務的關鍵鏈路上的某個關鍵產品質量不過關,問題頻發,可是業務已經跑在上面沒法簡單替換,這是讓人很無奈的事情,不少架構老司機對此場景應該深有體會吧。
11、浪費是創新的副產品
即便在同一個公司中,在主流技術棧的基礎上,不一樣團隊適當引入一些不一樣的技術棧,好比一個公司主流的技術棧是Java,有些前端團隊會嘗試用Nodejs開發應用,有些大數據團隊會採用Python開發應用(Python裏頭有不少數據分析庫)。這些作法和第二點提出的少便是多並不矛盾,根據業務場景的須要,適當引入一些互補的技術棧,適度冗餘能夠促進團隊創新。
再舉個例子,阿里在發展的過程當中,曾經發展出兩套技術體系,一套是淘寶體系,一套是B2B體系。有一段時間內,兩套體系並行發展,團隊之間既競爭也相互借鑑,造成一個良性競爭的技術生態。聽說Dubbo最先就是B2B搞出來的,淘寶後面又搞了一套HSF(未開源),Dubbo和HSF之間相互借鑑因此功能比較相似,阿里在2014年上市前對技術棧進行了整合,集團統一使用HSF,Dubbo則繼續活躍在開源社區,成爲中國開源軟件的一個傳奇,它的成功一方面源自阿里技術的沉澱,另外一方面也是B2B和淘寶相關團隊思路碰撞融合的結果。
12、技術的宗教信仰
不少技術人員對他們投入時間最多最熟悉的技術棧比較熱衷,有些甚至能上升到宗教信仰的程度,不一樣派系還會有相互鄙視的狀況出現(聽說PHP是最被鄙視的語言),有的還會發展到派系爭鬥的地步。以前我在一家互聯網公司,在容器PaaS平臺選型上出現了兩個派系,分別被戲稱爲K黨和M黨,K黨主張引入谷歌推的Kubernetes,M黨主張基於Mesos作定製,兩撥人都很是堅持各執己見,爭得不可開交。
其實我我的對技術的宗教信仰是很是排斥的,它是一種技術視野狹隘的表現,技術自己沒有絕對的好壞之分,只有適用場景和利弊之分。可是,技術的宗教信仰是一種客觀存在,有經驗的架構師在作技術選型時須要考慮這一層面的因素。
十3、經過背書作技術選型
和一線資深的架構師或者技術專家交流,獲取技術選型的專家建議,是一種比較靠譜的技術選型策略。專家是一種背書,他們踩坑無數才成爲專家,對不少技術有一手的實戰經驗,是真正know how的人,因此他們給出的建議通常都比較接地氣。
大公司是一個很好的背書,比方說Google,當初它推出Kubernetes的時候,其實我一開始看過架構設計以後是對這個產品嗤之以鼻的。可是Google的強大背書和號召力擺在那裏,用戶深信Google用腳投票,一開始架構設計很差不是根本性問題,只要有足夠的用戶造成社區閉環,這個產品就會不斷長好長大。目前K8S已經基本壟斷了容器PaaS平臺市場,它的成功很大程度歸結爲Google公司的背書影響力。因此,綁着技術型大公司這個背書作技術選型,大機率不至於大錯(固然不是絕對)。
Github上的星的數量也是一個重要的技術選型參考,同時還有項目代碼和文檔更新頻度(尤爲是近期),這些指標直接反應開源項目的社區活躍度和生命力。
十4、實踐出真知
實際評估一項技術時,最靠譜的作法仍是詳細研究其文檔,作一些樣例和測試,對性能有要求的則必須實際作充分壓力測試得到真實性能數據。對於開源的產品,若是處在業務的關鍵鏈路上,則建議把代碼拉下來通讀梳理一把,深刻理解其內部設計和架構,有的還須要根據企業業務場景適當作一些定製。
經過初步評估,仍須要尋找必定數量非關鍵試點項目(pilot project)作試水躺坑,通過初步生產驗證,才能夠考慮逐步擴大生產普及的規模。
實踐出真知,對於那些長期在一線實戰和積累的架構師,他們最終將得到良好的技術選型的sense和對新技術的敏銳性。
十5、技術的落地
簡單回顧下我國遼寧號航母的歷史:1999年中國購買了瓦良格號,於2002年3月拖回大連港,2005年4月開始由中國海軍繼續建造改進,2012年9月正式改名遼寧號,交付中國人民解放軍海軍,2013年11月,遼寧艦從青島遠赴中國南海展開爲期47天的海上綜合演練,標誌着遼寧號航母開始具有海上編隊戰鬥羣能力。我國前先後後花費超過10年才讓遼寧號航母初步造成戰力能力。
技術和武器同樣,你引入一個技術是一碼事,真正落地造成戰鬥力或者說產生業務價值徹底是另一碼事。技術通常有落地週期:引入,定製改造,小規模試點,再到逐步擴大生產規模,這個週期可長可短,對於一些基礎性和重量級的技術,或者涉及大規模遺留系統升級改造的技術,通常週期比較漫長(可能時間跨度長達1年甚至幾年),對於這類技術的引入和落地,架構師須要高屋建瓴,通盤考慮,制定落地計劃,分階段推動技術的落地。
十6、定製、自研仍是購買
這個問題比較複雜,很難一律而論,和企業的業務和團隊規模,架構甚至文化等諸多因素有關係。我我的遵循的兩個簡單原則分別是:
- 若是不是你最擅長,也提供不了差別化的競爭優點的技術則直接用開源或者購買。當心Not Invented Here症狀,避免重複造輪子,始終牢記達成業務目標纔是重點。
- 當企業的業務和團隊規模達到必定階段,對於處在業務關鍵鏈路上的核心技術,必需要有必定的定製甚至自研能力。創業公司儘可能用開源或者購買雲服務,驗證業務模式是第一優先;當你的業務模式得到驗證,業務和團隊達到必定規模,則需逐步考慮對核心業務鏈路上的技術進行定製甚至自研,以得到更大的靈活性;若是你成長到接近BAT那個量級,那麼大部分核心技術必然是定製甚至自研的,不然沒法支撐那個規模。
十7、寫在最後
本文僅限我的經驗視角,技術選型理念僅供參考借鑑。每一個企業的具體上下文(業務場景,團隊組織,技術架構等)各不相同,每一個架構師的背景經驗也各不相同,你們要結合實際本身作出選型,沒有最好的技術,只有相對較合適的技術。另外,好的技術選型是相互借鑑甚至PK出來的,歡迎你們討論,給出本身的技術選型思考。