創業公司CTO談創業公司技術選型

技術瑣話發表於2018-11-27

作者介紹:胡鍵超過15年軟體研發經驗,先後任職於中興和SAP,現專注於工業物聯網創業,任上海圭步CTO。具有豐富的產品研發和專案實施經驗,擅長圍繞裝置資產和生產管理提供物聯網端到端解決方案。他同時還是CSM和活躍的社群活動組織者,在西安組織過多場HiBlock區塊鏈技術社群活動並做分享。

作為技術人員,對於“技術選型”一詞應該不太陌生。簡單的說,技術選型就是技術決策,只要你在團隊中稍微有點地位,獨立承擔某項任務,就會面臨選擇,需要做出相應的決策。當然,這種細粒度地決策級別不是我要討論的重點。在本文中,我想分享一下我對於公司層面技術選型地觀點和看法,更確切得說是面向創業公司的技術選型。為何要重點突出“創業公司”呢?很簡單,因為到目前為止,我一直走在創業的路上。

好了,言歸正傳。在重點去談創業公司如何做技術選型之前,我們們先來看看技術選型的一般性原則。

技術選型的通用原則

選擇並不像看上去那麼美好,沒有選擇和選擇太多都會讓人痛苦,尤其是在當今技術大爆炸和開源專案滿天飛的今天,“選擇麻痺”應該是最讓技術決策者頭痛的毛病。要緩解它,就必須建立起我們自己的技術選型標準,或者說原則。

在經歷了這些年多次“艱難的抉擇”之後,我總結出了適合我個人的技術選型原則。

原則1:能否簡化開發任務?

這條原則顯而易見,如果選擇的技術無法幫助我們高效地達成目標,似乎沒有理由去選擇它。注意這裡的關鍵詞:簡化。完成開發任務的手段並不是唯一的,在眾多手段中間我們只關心哪個能夠讓我們生活得更容易。

同時,這裡還要避免一個不那麼顯而易見的陷阱:雖然簡化了手頭的任務,但帶來了其他方面的複雜性。比如,引入Kafka確實帶來了一系列的好處:流量削峰、簡化了任務分配和服務非同步化等等,但由此也帶來了一系列其他的複雜性,比如:運維的複雜性和事務的複雜性。那麼,作為決策者就要評估是否需要這樣一個複雜的方案,是否採用簡單地方案就能完成目標,如:日誌表 + 定時任務。

原則2:是否符合組織內的主流技術路線?

大多陣列織都會有一個主流的技術路線,技術團隊如果採用的技術五花八門,會大大增加技術管理的成本。技術路線,是在進行技術選型時必須要面對的問題,儘可能地選擇符合公司技術路線的技術或工具,這樣有助於工作的快速推進。

當然,凡事無絕對,當可見的好處遠大於學習新技術的成本和風險時,在可控範圍內冒險一試未嘗不可。但需要提醒的是,除非是極端情況,這種情形其實並不多見。因為當前豐富的開源工具已經提供了充分的選擇,在大多數情況下時能夠讓人找到既滿足自己要求同時又符合組織技術路線的工具。這裡我假設貴公司的技術路線並不是那種劍走偏鋒型別。

原則3:是否普及程度高或者學習曲線平緩?

普及程度高,有利於很快找到合適的人直接上手開幹;學習曲線平緩則有利於在缺人時快速將現有人員切換到現有賽道。一般來講,普及程度高的技術或工具,大都沒有陡峭的學習曲線。反過來就不一定了,比如我公司一直使用的Grails,在國內的普及程度就遠低於所謂的SSH或SSM。但其學習曲線一點都不高,而且開發效率數倍於前者。

這條原則直接著眼於技術選型對於人員管理的影響,滿足這兩點的技術或工具都將大大降低人員管理的成本,對於招聘和人員流動都有積極的影響。

原則4:能否得到有效地支援?

這裡的支援可以來自於兩方面:外部和內部。能夠方便地獲得外部支援一方面說明了專案的普及程度,另一方面也反映了專案的活躍程度。前者的好處在上面已有說明,至於後者,則說明專案在與時俱進,對於新出現的使用場景大機率有較好的支援。

即使有很好的外部支援,也不意味著就應該放棄內部支援能力的建立。原因很簡單,隨著使用的深入和業務的發展,遲早會遇到自己公司特有的需求,而這個需求還沒有廣泛到從外部就可以直接獲得很好地支援。此時,只能藉助自己的力量把坑填平,這樣才不至於以往的技術投資打水漂。

從獲得支援的角度來講,這條原則相當於對於上一條原則的補充說明。

原則5:是否有助於規範開發流程?

這一條原則的可能並不是那麼明顯,在此我想表達的觀點是:要麼有助於建立開發流程或套路,要麼對現有的流程有支援。

還是以前面提到的Grails為例,典型的Grails應用開發主要就是:

  1. 開發Domain Class

  2. 開發Service

  3. 開發Controller

  4. 開發View

透過將應用本身拆解成這樣的關鍵元件,從某種程度上來講既規範了開發內容和流程,同時也可以讓開發者快速地抓住要點,建立大局觀,迅速進入狀態。

另一個例子則是以太坊Dapp開發框架Truffle,其對於我們們習以為常的開發流程提供了直接支援:

  1. 建立專案

  2. 建立合約

  3. 構建合約

  4. (自動化)測試合約

  5. (自動化)部署合約

正是由於這樣的支援,使得Truffle成為以太坊開發的不二之選。

架構和工具的選擇差異

最後,作為第一部分的結束,我簡單談談架構選擇和工具選擇的差異。這裡,我不會教條的去大談特談架構和工具差異,因為這類帶學術性質的討論本來就不是我的喜好。

在我看來,架構更多地落在方向層面,而工具則著眼於執行層面的細節。既然如此,那麼兩者的選擇順序和差異就一目瞭然了:先定架構再選工具,而架構的選擇由場景決定。比如,面對高效能要求的場景,我們首先要做的是選擇哪一種架構模型:Actor還是STM;在定下來Actor之後,再選擇用AKKA,還是Erlang,或是Vert.x,又或是GPars?

創業公司如何進行技術選型?

技術選型工作並不會因為創業公司就變得輕鬆,相反,由於創業公司本身的不確定性和階段性,反而有其獨有的特點,在不同階段對於上述原則的優先程度和取捨也會有所變化。在本文的第二部分,我將針對處於不同階段的創業公司給出我自己的技術選型標準和建議。

草創期

處於草創階段的創業公司技術隊伍一般不會超過10人,在這個階段,公司最主要的目標就是儘快將核心業務快速上線,讓其接受市場的考驗。作為技術領導,我們通常會面臨:

  • 現有的人手永遠難以滿足不斷增長的業務需求。這句話有幾層含義:

  • 招人難,這是行業內永恆的主題,但對於小公司尤其突出。

  • 留人難,小公司資源有限,當員工覺得在此處自我修煉的任務完成,很自然會去尋找更大的平臺。

  • 變化快,相比起成熟的業務,草創階段一切都處於摸索階段,隨時都會調整方向和策略,由此導致需求的變化速度極快。

  • 上線壓力大,不太可能讓你先開發個半年再上線。更常見的方式可能是以月甚至以周或天的方式持續迭代,釋出產品。

  • 對於質量的要求只要達到基本可用即可,但要求隊伍具備快速地填坑能力。

  • 請注意,這裡指的質量基本可用並非是指低質量,而是指某些非功能性的質量要求並非那麼高,比如高效能、高可用等等。只要基本得到滿足即可,並不要求你在這個階段就造一個淘寶或京東。

鑑於以上的基本事實,對照前面的原則,可以很容易地排出優先順序:

  • 為了能讓開發速度趕上需求增長速度,顯然要求:

  • 能夠簡化開發,幫助快速開發

  • 普及程度高或學習曲線不那麼陡峭,從而降低人員管理的成本

  • 為了能支援快速迭代,自然需要:

  • 有助於規範開發流程,對業界廣為人知的工程實踐有直接的支援

  • 為了能讓團隊快速填坑,那麼希望:

  • 能夠有效地獲得支援,有助於快速填坑

這裡,我來說說為何當初選擇Grails作為我司的主要開發工具,而不是市面上爛大街的SSH或SSM。

  • 簡化開發,Grails在這個層面提供了數倍甚至10倍於後者的開發效率,究其原因:

  • 無處不在的CoC(慣例優於配置),對於常見的程式設計實踐以慣例的方式引入,基本消除了繁瑣配置的需求。

  • 提供了各類高效的開發部件,極大程度降低了開發人員的要求,即使是小白,按照手冊進行開發,也能快速開發一個像模像樣的應用。由於已經將常見的最佳實踐內建,按照這種模式開發出來的應用天然就對常見的開發問題免疫,較之SSH或SSM之類已經處於不同的層次。比如:樂觀鎖、SQL隱碼攻擊、XSS攻擊等等。

  • 豐富的外掛可以快速獲得框架本身不具備或者不提供的能力,如Spring Security外掛和Spring Security REST外掛可以快速地讓API應用支援JWT和許可權驗證。

  • 普及程度或學習曲線,Grails在國內的知名度遠遜於其在國外的知名度要拜國內的培訓班所賜。

  • 從歷史淵源來講,Grails本身就構建於Spring之上,同時曾經也被SpringSource收購,作為其工具鏈的一員。(注:Spring幕後的公司Pivotal於2015年終止了對於Grails的資助,但Grails目前依舊處於良好的發展勢頭。前不久,Grails團隊又推出了新一代開發框架Micronaut。)

  • Groovy語法對於Java開發者來講幾乎可以做到無痛遷移。

  • 對於規範開發,Grails同樣也不落人後:

  • Grails應用有很明顯的規範套路,參見上述原則5的描述。

  • Grails支援常見的開發實踐,如:自動化測試和DB Migration,可以很方便的跟Jenkins之類的CI/CD工具整合。

  • 從獲得支援方面,看看StackOverflow、相應的郵件組和它的Github倉庫即可。

由於時間對草創階段的公司來講是最稀缺資源,我強烈建議作為技術領導的你在此方面花些時間和精力。我個人喜歡透過引入好的工具來獲得額外時間,即使它顯得稍微有點偏門,也無所謂。因為好的工具通常:

  • 可以降低對於開發人員的要求,從而節約招人時間和縮短因人員流動而引起的效率減緩時間。

  • 快速實現業務需求,從而贏得比競爭對手更多的時間。

  • 將你的優勢構建於前人的智慧之上,避免了潛在未知的問題,提前消除了入坑和爬坑的時間。

不客氣的說,選擇一個平庸的工具固然沒什麼大錯,但你可能最多獲得平庸的結果和效率。

發展期

假如熬過了草創階段,那麼發展良好的你將迎來最具考驗的階段,發展期。此階段,人員不會超過50人,同時還要兩線作戰:

  • 保障線上業務的正常運轉

  • 按時交付層出不窮的新任務

這樣的考驗對於任何技術團隊來講都是艱鉅的,因為在這個歷史時期,雖然看似人手有所增加,但具有以下特點:

  • 人數雖多,但整體來講質量還難以與那些大廠匹敵,面對兩線作戰難免會出現顧此失彼,成天救火的局面。

  • 在草創階段鍛煉出來的技術骨幹經驗並不老道,缺乏硬仗的經驗,你仍然需要花很大的精力來處理技術層面的事情。

  • 人數的增多,導致了溝通成本的增加,如果沒有好的、顯式的開發流程做支撐,就很難撐過當下複雜的局面。

另一方面,從業務角度來講,給技術也帶來的新的要求和挑戰:

  • 更高的質量要求,原本不那麼重要的非功能屬性會變得越來越突出,比如:高效能、儲存的擴充套件性等等。

  • 要求邊開飛機邊換引擎,在保障線上業務正常執行的同時,償還技術債。

  • 需求產生的速度非但不會減緩,反而會承上升趨勢,因為公司的接觸面變大了。

在這樣的背景之下,作為技術決策者,可以按照這樣的優先次序去考慮技術選型:

  1. 有助於規範開發流程

  2. 有助於簡化開發任務

  3. 高普及度和平緩的學習曲線

  4. 能有效地獲得支援

並且,在這個階段架構選型將會至關重要,否則難以達到業務所要求的質量目標。這在前一個階段通常是不存在的,在我看來,草創階段最重要的設計莫過於資料庫設計。至於其他,都可以商量。

同樣的,我將以我司的工業物聯網接入層的架構變遷來說明一下。

在草創階段,我們的接入層由以下幾部分組成:

  • Socket Server,負責線上裝置連線管理,解析資料包、儲存資料和報警等功能。

  • 後設資料存放於Postgresql

  • 實時資料存放於MongoDB

隨著裝置接入數量的增加,這種設計開始捉襟見肘,架構改造勢在必行。經過一系列的改造階段,最終的架構變成:

  • Socket Server,只負責裝置連線管理

  • Processor,它負責接收Socket Server傳來的TCP包,將其解析成最終的資料格式,同時負責報警

  • Ghost,它負責將Processor解析出來的資料儲存起來

  • 後設資料依據存放於Postgresql

  • 實時資料存放於HBase

其中,Socket Server、Processor、Ghost透過Kafka串聯起來,後一階段的處理負責從Kafka相應的Topic中拿到前一階段處理好的資料,處理完畢之後再放入相應的Topic,交給後續的處理器處理。

或許有人會說這就是標準的流處理場景,不如干脆直接用相應的框架算了。沒錯,我的確曾經動過採用類似Storm或Spark的念頭,但考慮到其帶來的複雜性和團隊對它們並不熟悉,最終採用上面的土方法應對了。到目前為止,它還穩定的執行著。這裡還有一個背景:我們所面對的是大型工業裝置,屬於To B場景,從業務角度講,裝置上雲的速度不太可能一夜就暴漲上萬臺。因此,採用以上的架構足以應付相當長一段時間內的機器數量增長。

其他技術考量:

  • Socket Server、Processor和Ghost本身就採用高效能的框架Vert.x來編寫,效能非常高

  • 採用Kafka而非直接講上述三個組成一個叢集,然後利用Vert.x的Cluster Eventbus進行互動,則是利用Kafka日誌永續性的特點,避免service掛了之後,丟訊息。

  • 分拆帶來的一個附加好處就是可以方便的按需部署各個服務,因為Socket Server和Ghost相比起Processor來講,並不易變,將變化率不同的元件分拆之後,可以更好地維護各個元件。

  • 棄用MongoDB,轉投HBase則是由於MongoDB的儲存擴充套件性相比起HBase要差很多,而且運維成本也很高。

作為承前啟後的發展期,架構選型是其關鍵所在,稍有差池,在草創階段積攢下的優勢就有可能灰飛煙滅。確定下架構之後,至於選擇自建或是符合要求的雲服務,這種選擇題就好做多了。

成熟期

恭喜你,達到此階段的創業公司可謂是有所小成,打過硬仗的技術團隊的實力也進一步得到增強(不論從人數上來講,還是從素質上來講)。相比起草創階段的流寇,發展階段的山賊,現在的隊伍可以算得上是一隻正規軍了。

業務上,開始慢慢穩定,形成了固有的套路和做法,即使有新需求,也並非像以前一樣沒有參考和不穩定。另一方面,技術上的積澱也越來越多,不論顯式地或隱式的,公司已經有了自己的技術路線和規範。同時,在戰火裡成長起來的骨幹也都能獨當一面,你不再需要去做低層次的技術決策。

想必各位已經猜到,作為技術領導的你,此階段地當務之急當是建立技術規範,明確技術路線和要求。有條件的還可以組建架構師委員會,甚至進一步將團隊分拆成基礎框架和業務應用兩部分,將低層次的技術決策下派給相應的技術帶頭人。此階段,最重要的原則莫過於:是否符合組織內主流技術路線和是否有助於規範化開發流程。

很遺憾,雖然我很想像前兩節那樣舉一些個人實際的例子來佐證,但由於我所處的公司尚未達到此階段,故只能在此紙上談兵。至於例子,只好作罷。

總結

技術選型是技術領導日常工作的一部分,但就不同階段的公司而言,技術選型的標準並非一成不變的。針對公司不同階段的關注的重點,本文簡單談及了相應的標準和原則,同時結合自身給出了相應的例項。

說到底,技術要為業務服務,技術選型不能是技術人的自嗨,更不能是“面向簡歷”的決策結果。只有把握了這個最終原則,我們才能真正客觀的看待當前的技術問題,相對客觀的履行作為公司技術帶頭大哥的職責。

最後,雖然全文以“公司”為名,但其實只要將公司兩字換成其他,比如“業務線”,其實也未嘗不可。比如,成熟公司內部的創新,其整個過程與創業公司的發展其實非常類似,這種情況下,只要大領導支援,當然也可以採用相對激進的做法進行小範圍內的“不符合公司當前主流技術路線”的技術選型。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/31562044/viewspace-2221797/,如需轉載,請註明出處,否則將追究法律責任。

相關文章