雪球首席架構師唐福林:雪球服務化實踐歷程
原創(chuàng)服務化的話題在兩三年前很熱,眾多公開場合都在說,最開始是亞馬遜、Twitter,緊接著就是國內的淘寶、微博都在談服務化。在這之后,感覺這個話題慢慢趨向過時,之所以有這樣的感覺一是大公司或因人員流動或其他各種關系大家做的服務化都大致相似,二是當下并沒有大量的創(chuàng)業(yè)公司有這樣需求。其實每年都會有一些正在從小到大的成長,這個過程中總會碰到服務化的問題,是繞不過的。
當一些初創(chuàng)公司遇到人員、業(yè)務、流量等膨脹之時,還是需要有類似的解決方案來借鑒。遇到這樣的問題,如何解決,馬上解決還是緩一緩再做。每當這個時候,看淘寶怎么做,微博怎么做其實并不適合初創(chuàng)公司的場景。因為所面臨的問題不一樣,如人數(shù),背景做事方式等都有所不同。在由51CTO高招主辦的“CTO訓練營”活動現(xiàn)場,雪球首席架構師唐福林分享了其公司在面對這個問題的時候是如何做的。他表示,這其實痛定思痛或說是反思。雪球的解決方案也并不是很理想,但可以給大家做一個前車之鑒。
關于雪球,關于唐福林
演講開始,唐福林簡單介紹了雪球的發(fā)展和自身的經(jīng)歷。
雪球,一個聰明的投資者的社區(qū),有Web1.0:新聞資訊,股價信息,K線圖、Web2.0:SNS 訂閱,分享,聊天、Web3.0:移動APP,交易閉環(huán)等業(yè)務,還有非互聯(lián)網(wǎng)業(yè)務,如做資產(chǎn)管理,私募工場,是一個典型的創(chuàng)業(yè)公司。雪球當前員工數(shù)剛好過100,其中技術人員占50%?,F(xiàn)在的技術棧由Java,Scala,Akka,F(xiàn)inagle,Nodejs,Docker ,Hadoop組件組成。當前是租用IDC機房自建私有云,正在往“公私混合云”方向發(fā)展。
唐福林,雪球首席架構師,負責雪球大數(shù)據(jù)體系建設及服務性能與穩(wěn)定架構優(yōu)化工作。曾任微博平臺資深架構師,微博技術委員會成員,深度參與微博快速增長期的性能和穩(wěn)定性問題解決。
雪球服務化歷程
在講雪球服務化歷程之前,唐福林簡單介紹了雪球公司業(yè)務的發(fā)展歷程,如下圖:
服務化歷程之雪球技術發(fā)展
上圖為,以2012年初為基準,雪球的團隊人數(shù),服務個數(shù)和代碼行數(shù)的增長趨勢。
服務化歷程之技術演進
唐福林表示,最初整個雪球服務是在一個大一統(tǒng)的工程里實現(xiàn),內部命名為Snowball ,就是滾雪球的意思。 Snowball系統(tǒng)從 2012年到2013年初一直運轉良好。但隨著2013年業(yè)務的膨脹,代碼的增長,團隊的擴張,漸漸出現(xiàn)了很多問題,比如重復代碼,比如代碼不夠規(guī)范,比如測試困難,比如溝通成本越來越高,比如不相干的功能在實現(xiàn)上存在耦合等。
- 針對業(yè)務膨脹。開始了模塊化改造,將底層基礎模塊抽取成公共庫,做到代碼級的服用;
- 針對代碼量增長過快。采取了一種在國內互聯(lián)網(wǎng)公司不太常見的措施:引入一種描述能力更強的語言 scala。簡單來說,它是一種 jvm 上的混合語言,混合了面向對象編程和函數(shù)式編程兩種方式,它的編譯器其實就是一個 jar 包,源碼會被編譯成跟 java 一樣的 bytecode,然后在 jvm 上運行。在 scala 中,可以無縫的調用絕大多數(shù) java 的庫。scala 語言的描述能力很強,平均下來,同樣的邏輯,scala 語言實現(xiàn)大概會是 java 實現(xiàn)長度的 1/5 到 1/10 的樣子。
- 針對團隊的擴張。開始推行一種工程師文化:鼓勵大家使用新的更好的技術和工具,鼓勵大家制造更多的工具和輪子,鼓勵大家交流分享。
唐福林在演講中說到:“在那個時候,推行工程師文化的兩個重大結果,一是在線上服務和基礎設施層引入了 scala,二是在基礎設施層引入了 docker 。這兩個決策在現(xiàn)在看來,當時的引入肯定是沒有經(jīng)過深思熟慮的,后來的一路上也是踩了不少坑,當然也付出了很大的時間和精力代價。但是當回過頭去看的時候,還是很慶幸引入了這些基礎設施,它們既幫助雪球完成了功能,方便了部署,也幫助雪球在技術上有了積累,在團隊上有了進步”。
隨著時間的推移,雖然采取了上述一系列的措施,問題有了一定程度的緩解。但隨著業(yè)務繼續(xù)加速膨脹,代碼加速增長,團隊加速擴展,問題還是不可避免的越來越嚴重。這時候雪球到了一個大的關口:流量增長到一定程度,代碼模塊之間開始互相影響,一個模塊的性能問題很快擴散到影響全站訪問,git 分支合并開始頻繁出現(xiàn)沖突,開發(fā)迭代速度明顯受影響。另外一個比較嚴重的問題是,不同的模塊帶進來的第三方依賴偶爾產(chǎn)生沖突,解決起來很麻煩。面對這樣的嚴重的問題,雪球很對采取了進一步的對癥下藥:
- 對穩(wěn)定性,性能互相影響的問題,標準解法是切分流量單獨部署
- 代碼合并沖突,第三方依賴的標準解法就是:服務化拆分。
唐福林在演講中說到:“對于像雪球這樣的小公司,服務器不多,服務化拆分后會嚴重增加部署成本,包括線上和測試環(huán)境。針對這個問題,當時采取的辦法是:Docker 容器化?,F(xiàn)在大家可能覺得這也是一個標準解法了。但在兩年前,Docker 的版本號還小于 1.0,這樣的選擇,不能不說是具有相當?shù)那罢靶缘?rdquo;。
服務化歷程之服務化框架選擇
做服務化,就面臨一個服務化框架的問題。自己開發(fā)的選項是早早就被放棄了,畢竟公司所有技術人員加起來,都不如淘寶開發(fā) dubbo 的團隊人多。 選一個現(xiàn)有的?因為已經(jīng)引入了部分 scala 業(yè)務代碼,rpc 框架也必須要支持 scala 才行。理論上,所有純粹的 java rpc 框架,scala 也都能用,但是,想要以純粹的 scala 的方式寫代碼的話,調用java方法和處理java的參數(shù),返回值對象的時候,都需要轉一下才行。另外一個考慮因素就是,這個框架必須是開源的,經(jīng)歷過大廠驗證過的。最后,選定了 finagle 。
服務化歷程 - Finagle 介紹
Finagle支持多協(xié)議適配,對 client 端和 server 端來說,它具備標準的連接池,失敗檢測重試,負載均衡,監(jiān)控統(tǒng)計,追蹤,分區(qū) etc。
它的編程模型如下:
- 所有的客戶端操作都返回一個 Future,也就是說,所有操作都是異步的,可以往 Future 里面放 callback 回調,也可以把多個 Future 串起來。
- 所有的服務抽象成一個個的 Service:每個 service 的輸入都是接收一個 request,返回都是一個 Future[Response]。
- 所有的策略實現(xiàn)都是一個個的 Filter,F(xiàn)ilter 是包裝在 service 外面的。
服務化歷程之嘗試、推廣、升級、服務治理、收尾
唐福林表示,F(xiàn)nagle看起來功能強大,又非常符合當時的各種期望。于是,就引入雪球。之后經(jīng)過嘗試、推廣、升級、服務治理和收尾等環(huán)節(jié),直到2015年9月,F(xiàn)inagle架構如下如:
2015年9月 Finagle架構圖
未來與微服務化
當前這個方案最大的問題,還是在于開發(fā)團隊的hold程度,簡單來說,Scala是一門會用不難,會用好還是挺難的編程語言,所以,用它寫業(yè)務邏輯問題不大,但用它來寫基礎設施,那就需要一個精煉的技術小組才能搞定了。而 finagle 呢,Twitter 的那些開源代碼開發(fā)人員,那是相當?shù)撵偶?,有的時候,團隊里對 finagle 最精通的人,也會忍不住連連贊同。
唐福林演講中說到:“雪球的 scala 技術團隊免不了有一些人員更替,有轉產(chǎn)品的,有轉管理的,有轉去做另外的業(yè)務項目的,導致后面的框架升級和二次開發(fā)力量嚴重不足。加上 finagle 自己迭代速度快,向后兼任又差,整個一個 no zuo no die why you try 的感覺”。于是,唐福林個人花了差不多兩周的時間,做了一個簡單版本 rpc 框架的嘗試。得益于在微博做 motan 框架的經(jīng)驗和教訓,框架開發(fā)很快,開發(fā)出來后,拿給整個技術團隊做討論的時候,才發(fā)現(xiàn)問題很多:再后來,團隊在針對 rpc 框架的接下來需求的討論過程中,越討論越覺得方向有一些偏:大家對基礎設施需求的重點并不是在 rpc 調用框架,而更多在于:大量的小服務,開發(fā)業(yè)務邏輯的便捷性,升級基礎包的便捷性,單節(jié)點的運行狀態(tài),數(shù)據(jù)收集,監(jiān)控報警的便捷性等等。于是,在未來,會把接下來服務化工作的重點定義成:微服務化,具體來說,就是開發(fā)并維護一個滿足雪球自己業(yè)務需要的微服務容器。
思考和教訓
當服務到了一定程度,做服務化是肯定的。但不建議自己做服務化框架,可以找一個比較成熟一點的東西來做。穩(wěn)定性和可用性是一個最重要的工作。做服務化拆分時會引起穩(wěn)定性和可用性下降,更何況如果拆了很多個不同的服務,由不同的人去維護,很容易出問題,所以一定要重視單個節(jié)點的一致性。 可以嘗試新技術,但要保證技術先進性與技術棧一致性。之后,唐福林還從技術深度與技術新鮮度、團隊擴張和成員更替、個人興趣和團隊合作等方面分享了很多寶貴的經(jīng)驗。
在演講最后,唐福林提到了細節(jié)和規(guī)范。他說:“想要用好一個框架,有很多細節(jié)需要仔細注意的。如 finagle 的重試邏輯,跟我們平常說的不太一樣,retry=3 的時候,并不是重試三次,而是加上第一次嘗試,一共三次,也就是說重試2次。 在使用開源框架的時候,首先遵守框架本身的規(guī)范,開源社區(qū)的規(guī)范,然后在這個基礎上,制定自己(小團隊)的規(guī)則,或者叫使用約定。規(guī)則成熟后,最后形成固定的(公司大團隊)的規(guī)定。”
了解更多訓練營內容:http://x.51cto.com