如何評價知乎開始將核心業務向 Go 技術棧遷移?

https://gocn.io/m/question/1513

職位描述 ? 負責知乎核心業務模塊向 Go 技術棧轉變的推動及相關的框架和基礎組件開發工作

? 負責優化知乎核心業務的性能指標和資源消耗

? 負責指導相關工程師,按照質量要求完成相關業務使用 Go 技術棧進行重構的工作


記得上次遷移技術棧的時候把Web給搞殘廢了,到現在PC半死不活,手機徹底涼了

希望這次把知乎給徹底弄廢了,也算是為社會做點微小的貢獻。


golang寫伺服器程序確實好啊, 清爽、乾淨、鋒利。

從運行的層面講, 代碼編譯出來的結果乾乾淨凈的一個包, 啥都不依賴,不用裝各種亂七八糟的環境,不會出現個各種兼容性問題,程序邏輯沒問題,基本上啥都不用操心, 運維同事最喜歡了。

從代碼的層面講,在golang中,定義的變數和導入的包不使用,代碼編譯就通不過。如果剛從其它語言轉過來,會覺得超級不自在。 但習慣後就會覺得這是一個牛逼的特性, 它從編譯器層做面做約束,杜絕代碼的噪音雜質,提高可讀性,減少出錯率。Java的話還好,像php之類的語言,項目久了,哪些代碼有用哪些代碼沒用,壓根就分不清楚。

我個人非常不喜歡亂七八糟的東西,喜歡簡單、井井有條的, 寫代碼、 玩伺服器也一樣, 在這一點上golang是任何其它主流技術不能比的。 不要小看所謂的簡單,等到項目和架構複雜到一定程度, 簡單所帶來的對成本的節省是無比誘人的。 像知乎這種大網站,鐵定會面臨高複雜性和高成本運維的問題, 最直接的解決辦法自然是換技術棧,這個時候顯然他們會發現golang是最合適的。

至於性能方面,golang顯然可以拍著胸脯自信的對python說: 老子就是比你牛逼。 python連個屁都不敢放的。


我猜用 Python 每個月花在伺服器上的開銷(以及招人成本)已經高於招 go 工程師來『重構』的成本,用 Go 確實能減少很多容器的使用,減少資源佔用。一開始用 python 感覺很可能是因為 quora 選擇了 python(對標產品),quora 創始人 Adam 曾經解釋過為什麼選擇 Python,簡單說就是:C#被微軟束縛,不想用微軟技術棧;facebook因為歷史遺留問題使用php並不意味著php是個好選擇;不喜歡 java 的冗長繁瑣。當時 go 也沒流行,Quora最後選擇python並通過嚴格的單元測試控制質量。當然,以國內很多中小公司無規範,無文檔,無注釋,無單測,無靜態檢測的尿性,動態需語言後期會讓你維護得十分痛苦,雖然我覺得 python 是為了降低編程門檻的。

很多人只從技術不從成本、產品周期來考慮也是有失偏頗的。產品初期為了快速迭代、市場驗證等用動態語言能快速開發原型,產品成熟了穩定性和性能就越來越重要,核心業務換成靜態語言有好處,但一開始並不如動態語言搞起來快。用 Python 的一個好處是 python 是個多面手,運維、爬蟲、web 後端、數據分析等很多都能搞,但是在後端 Python 沒有明顯優勢。很多公司也很難僅僅用一個技術棧就能滿足所有需求(不同團隊,不同產品線),就是換技術也沒啥大驚小怪的,也不可能所有產品線都換掉,多學點唄 。(注意是『核心』『後端』業務,就是 qps 很高,需要很穩定,IO 密集領域)

https://www.quora.com/Why-did-Quora-choose-Python-for-its-development-What-technological-challenges-did-the-founders-face-before-they-decided-to-go-with-Python-rather-than-PHPwww.quora.com

We were sure we didn"t want to use PHP. Facebook is stuck on that for legacy reasons, not because it"s the best choice right now.[1] Our main takeaway from that experience is that programming language choice is very important and is extremely costly to change.

Python was a language that Charlie and I both knew reasonably well (though I know it a lot better now than I did when we started). We also briefly considered C#, Java, and Scala. The biggest issues with Python are speed and the lack of typechecking.

C# seemed pretty promising. As a programming language, it"s great, but:

  • We didn"t want to be on the Microsoft stack. We were up for learning something new, and MS SQL Server actually seemed pretty good, but we knew we"d need to integrate with lots of open source code that has only second-class support for .NET, if it supports it at all. Also, most of the best engineers these days are used to open source stuff.
  • We didn"t want to take the risk of being on Mono (an open source implementation of C#/.NET). It"s not clear how long funding will be around for that project, and I"d heard of various performance problems. Plus, it seemed like everything else in the C# ecosystem would assume we were on the Microsoft stack.

For a lot of little reasons, Java programs end up being longer and more painful to write than the equivalent Python programs. It"s also harder to interoperate with non-Java stuff. Scala had a lot of the downsides of Java and the JVM, although it wasn"t quite as bad. The language seemed a little too new and like it would bring some unnecessary risk (for example, who knows how good support will be in 10 years).

Two other languages we very briefly thought about were OCaml and Haskell (neither had big enough ecosystems or good enough standard libraries, and both were potentially too hard for some designers/data analysts/non-engineers who might need to write code).

We decided that Python was fast enough for most of what we need to do (since we push our performance-critical code to backend servers written in C++ whenever possible). As far as typechecking, we ended up writing very thorough unit tests which are worth writing anyway, and achieve most of the same goals. We also had a lot of confidence that Python would continue to evolve in a direction that would be good for the life of our codebase, having watched it evolve over the last 5 years.

So far, we"ve been pretty happy with the choice. There"s a small selection bias, but all of the early employees who"d been working with other languages in the past were happy to transition to Python, especially those coming from PHP. Since starting the following things have happened:

  • Python 2.6 got to the point where enough of the libraries we used were compatible with it, and we made a very easy transition to it.
  • Tornado (web framework) was released as open source, and we moved our live updating web service to that.
  • PyPy got to the point where it looks like it will eventually be usable and will give us a significant speedup.

All together, these give us confidence that the language and ecosystem is moving in a good direction.

[1] What are the horrors of PHP? and Do Facebook engineers enjoy programming in PHP? and Why hasn"t Facebook migrated away from PHP? and What are some of the advantages of PHP over other programming languages? for more on that.


go顯然比python在做這些事情的時候要強,屁股想一下也知道。


知乎上線於2011年,彼時懂python的都遠沒有現在人多,更別說tornado了。python在當時是很好的人才篩選器(現在怕不是能爬小黃圖的都敢說自己會py了),除非真正熱愛編程否則一般為高薪而來的程序員會選擇投入產出比高的Java。

同幾乎所有創業公司起步一樣,早期的開發活動一切圍繞著「快速」二字 ,加之包括cto在內也不是特別熟悉tornado,欠下的技術債便有了積累的條件。

之所以這麼說是因為在翻看知乎員工早期的回答和跟他們交流情況來看,知乎沒有利用到tornado太多的「協程」特性。畢竟在當時大量的中間件無法被tornado的IOLoop直接接納。如果要充分利用tornado的威力就需要讓ioloop接納你的fd,在這個前提下你才能寫成全非同步協程代碼。要實現這個前提需要從其iostream繼承類實現讀寫handler介面來對組件(比方說redis)的connection進行wrap。技術難度極大。一個簡單粗暴的辦法就是使用多線程,ioloop線程只負責會話管理,業務發生在別的線程當中。一旦架構設計成這樣,就步入了積重難返的道路了。這種架構後期只能靠堆機器,問題是別人有錢堆,你沒有錢來堆,服務在此時頻繁出現問題。即便後期人才儲備技術能力均已經追趕上來卻也很難把這種多線程架構回歸tornado單線程協程模型了(歷史包袱)。此時最好的方法就是來一次大換血。由於之前的經歷多多少少還是從協程當中獲取了一點收益,所以換血也希望保留甚至最大化協程收益,這個選擇很自然的就是go了。

在下並不認為這件事情(由py轉go)是語言本身的缺陷導致,它更多的是一種權衡吧,同時也暴露了即便是python技術棧的公司也不見得就對python有多麼深厚的積累的事實。所以不用借題發揮把py大肆批判一番,搞個大新聞。

微服務概念的落地方式是多種多樣的,隨著分散式服務的發展,未來代碼的開發集成也是走分散式化的模式,這麼來看動態,元編程能力且支持熱載入的python一定會發光發熱的。


我有預感... 以後的 BUG 數量和出現頻率可能不但不會改善還會變本加厲。。。


坐等知乎上市後改用java


go的確比python適合做工程語言


大部分互聯網服務都是io型的,很多性能瓶頸都是傳統同步io框架導致的。io模型一換,基本上基礎層面能優化的就不多了,更多的還是看讀寫架構設計。

go顯然是徹底解決了io問題,從底層消滅了同步io。計算性能和編譯速度,也是有巨大改進的,但這個稍微次要一些。

但go,對於大型業務項目來說,我們遇到幾個問題。

1、生態不完善

生態不完善,要麼自己造輪子,要麼心驚膽戰地去用開源的輪子。自己造輪子沒時間,一堆開源輪子也不知道是哪個阿貓阿狗寫的,特別不放心。前兩天遇到一個基礎conf庫,在get的時候進行delete,panic了。zk、redis、hbase等要命的玩意兒的client都不是官方的。

2、沒解決依賴問題

編譯是用文件依賴來解決,官方的解法(還沒完成)是靠git 版本實現,這就導致做業務拆分很困難(翻牆不易),不同業務想依賴同一個項目的不同版本很麻煩,只能各種山寨辦法模仿nexus。

3、語法問題

語法其實都是有利有弊,這裡也不算問題吧,只是我們做一些基礎輪子的時候,反射不強大,總是需要寫出一堆需要業務寫defer的邏輯,跨業務error也是坑。不太容易做到「面向亂搞編程」,防止使用者亂搞。

總之我的理解,目前go不太適合做稍微大規模一點的團隊替代整個技術棧,可以考慮做一些做小而美的基礎服務,比如像etcd這種東東。做大型業務,絕對會拖垮開發效率。

說實話,如果感覺機器性能吃的厲害,往往不是換語言的問題,當然人家願意搞,其實也挺好的。如果是我,在沒有歷史包袱的情況下,是不會選擇go的,我的價值觀是用技術成就商業,而不是用公司的資源去成就一門技術。


我覺得腳本語言的可讀性奇差,不知道大家有沒有同感.

用C++或者Java,再複雜的project,拿出某個函數, 都可以用IDE的跳轉, 看清楚幾個核心所屬的class的意思, 然後逐漸理解整個project. 腳本語言寫個函數連類型注釋都沒有,完全不知道函數的參數類型, 不知道他們有什麼method和data, 唯一可以依靠的就是變數 的名字. 但名字經常不那麼可靠.

所以我覺得腳本語言寫大型project基本上就是bullshit. 當然也有可能是我python沒學好的緣故.


「由A語言轉B語言就說明B語言比A語言好」是不是一種「政治正確」?

「語言至上論」是解決不了業務問題的,選Go也不行。

Go的優勢是文件易部署,協程機制相對成熟且簡單,以及靜態編譯語言的效率,還有就是編程模式相對簡單。這大概是現在越來越多企業嘗試Go的原因,除了知乎,B站也把核心部件從PHP轉到了Go。

那是不是說Python、PHP不行了?當然不是也不應該是這樣的。如果要堅持Python、PHP,也是沒問題。一個系統沉積太久的話,會產生很多大大小小、零零散散的「技術債」,這其間就涉及解決成本的考量,重構、重寫、抑或重新設計核心模塊或新模塊?由此又帶來技術選擇的問題。還有Python、PHP人才儲備的問題,還有團隊希望嘗試新技術的考慮。這些問題交織在一起,就不是哪個編程語言好跟壞這麼簡單的事兒了。

所以還是要回到業務層面來看技術解決之道。不得不說,Go的協程,一個「go」就能解決絕大多數問題,確實寫代碼很簡潔,Python新添的asyncio還是相對複雜,Future、Task等等還是有不少門道的。所以,技術永遠只有合適的,而沒有最佳的,也沒有非此即彼的好壞分明。我相信,如果團隊在Python方面積累厚實,且熱衷專註於Python,選擇Python應該就是個大概率事件。Python現在已經應用頗廣,特別是在AI領域帶動下,Python人才也不像以前那樣難找工作了,鐵打的營盤流水的兵,是不是知乎也面臨人才流動壓力?此外,畢竟Python的生態,在這麼多編程語言中,是數一數二的,Go雖熱,但在社區方面恐怕還是比不上Python、PHP,這也是一個現實問題。

知乎前端換了React,我沒感覺比原來的AngularJS進步,但不能就此說React不行。嘗試用Go寫一些原來Python的範圍,也是同理。而且一個系統同時應用多種開發語言、一系列技術棧,都是再正常不過的事了。

其實最想的還是想聽聽知乎開發團隊的解釋及說明。


go有更多的坑. 相信我, 還是java好.

然後哪怕java撐不住了, 換zing然後所以開發又可以放長假了.


簡單來講 用接近於無的編譯時間來達到接近c艹的性能。

性能是啥?性能就是錢啊。你知道一台標準的32核64G伺服器多少錢嗎?

你知道go的性能能到腳本語言的多少倍嗎?

go不火沒天理


知乎的業務還是偏簡單,選擇go寫業務伺服器和上容器確實能省一些開發工作量。但是涉及大數據部分,推薦,個性化,人群畫像,用go寫會花費巨大,聯調,bug修復還需要另外雇一批會java的工程師。這時候就能想起java的好處了。


Go不好招人,穩定成熟的組件太少,不久的將來可能會出現「如何評價知乎開始將核心業務向 Java 技術棧遷移?」


本來的也是隨手一答,結合這一兩年業務的感受,也沒想到會有這麼多人評論,感覺是黑的地方,大家笑笑就好

其實當初知乎用py的時候我就覺得,這是一家有情懷的公司,是一家有幹勁的公司。少折騰不代表不折騰,特別是當技術趕不上業務發展的時候,更多的是被迫。

於是開始調研,討論如果要用新語言替換掉一些py中間件,或者是前端組件(這裡指的是後端的前端),團隊更傾向於使用哪個語言開發。從團隊構成猜測,得出來的投票結果,JAVA,C#,或者是PHP,nodejs的票數應該比較低,而且鑒於他們已經開始有些中間件在嘗試過渡到go,接下來核心業務慢慢過渡到go也是在情理之中了。

在下的站跑的是PHP為主,業務量大了也是有撐不住情況,近幾年業務上來了,也有些奇葩需求,PHP有些天生的缺陷很難滿足這些需求,又因為技術債務無法遷移到swoole,17年上半年花了點時間把一些業務遷移到了go上面,可能因為是小廠,而且網上關於go的資料,基本上是停留在語言級別,要詳細了解內存分配,協程調度等詳細信息只能去看源碼,感覺還是有點力不從心。

17年下半年機緣巧合收集到了套JAVA代碼,出於研究目的又撿起了JAVA。

按理說JAVA從大學畢業就沒碰過了,但是總感覺做小Demo的時候阻力要比用go要小。應該,是人上年紀了適合我這種對付老婆和孩子老媽子還要對付程序的中年危機碼農。

說回主題,現在都微服務化了,用最適合業務的語言去解決,自然是最高效的做法,至於從招聘上看,應該是一條路走到黑了…

人家孫悟空一個筋斗十萬八千里,但是師徒四人最終還是要歷盡九九八十一難才能取得真經,這,也許就是問題真正的意義。

——原答分割線——

golang連個全功能的線程安全的map都沒有,java有個穩定的guava庫。(sync.map不算,過一兩個版本再說)

golang從性能上來說,大部分的benchmark也跑不過java的。(評論指出go跑得要比JAVA歡,是我太膚淺)

golang有什麼,binary比較小,支持協程。但是java也有akka啊

說快速開發,java有spring全家桶,golang好像沒有啥

……

數不下去了…


瀉藥

其實python在很長時間內是被高估了,如果當年不是因為google受不了c++,而使用python,就是那句著名的:

"Python where we can, C++ where we must"

我估計都沒有人還記得有這麼一門語言,當然python有python的好處,最大的好處就是用來做膠水方便,面對著一個legacy lib,甭管它是啥語言寫的,直接用python做一層wrapper就可以用了,這是python最大的特點,當然google在使用c++的過程中,也終於受不了c++繁瑣的特性,決定將其簡化了,而第一個嘗試就是python

此為背景,而無數的人看到google用了python,就開始興奮,哇,google用python了,那肯定沒問題啦,於是也就開始用python,所以python從一個差點被人遺忘的語言一下子被拉高了起來,甚至到現在被訛傳什麼大數據,ai專用語言,這都是搞笑的,腳本集中營都腰身一變成了大數據培訓班了

一時間,無數的startups都用了python,但是時間久了之後,google也發現,這似乎不是個事,因為腳本語言雖然在一小塊領域內,是比c++簡單,但是腳本語言也有它自己的問題,就是隨著範圍擴大之後,也不是那麼可控,也還是可以讓項目失敗,曾經發生過一件事,就是google的某個項目組,用python,用到後面,受不了了,最後還是換java吧,然後髮網上,然後無數人噴,說你們這群人不會用python,那個組的人回答很漂亮,如果連google的工程師都無法駕馭這種複雜度,那說明這不是人的問題,而是這個語言就不適合,如果你覺得你的工程師比google的還牛逼,那儘管上

所以google後來搞出了go嘛,如果python真能搞定問題,還搞go幹什麼?很多人也沒有注意到,在go誕生後,python他爹,黯然離開了google

go誕生的原因和理由,幾乎跟google自身使用python的理由一摸一樣,都是為了替換c++的,參考《Go語言之父談Go:大道至簡》網路上隨便搜:

這時候,我問了自己一個問題:C++委員會真的認為C++的特性還不夠多?當然,不同於Ron的玩笑,簡化這門語言必是一門更大的成就!也許這很可笑,但是請把這個想法記在心裡。

那如果google是這種路線,你覺得現在用python的那些公司和網站,下一步會做什麼?

跟著抄一遍嘛,很正常嘛,所以知乎這麼做不是很正常的事么?


我覺得用Go重構核心代碼是正常的,用C重構核心代碼也是正常的,Python的正確用法就是膠水的py去調用各種語言寫的庫,作為非IT從業者,個人從一開始的彙編(8051 8086 MASM32)到C到MFC到VB到C#,最後再到Python,用下來感覺Python特別適合做Starter,可以隨心所欲的寫自己想到的功能,基本能跟上思路,而其他語言(至少我會的幾種)很多時候需要停下思路去想該怎麼寫。當一個項目完工後,如果感覺速度不滿意,再考慮用其它語言重構影響性能的代碼,甚至整個項目重構,其實比一開始就用C這樣的語言快的多,畢竟那時候思路上的坑已經踩完了,只剩下怎麼用代碼實現了。


說明作為一個聚集了大量程序員的網站,知乎的技術決策層還是很有眼光的。

Golang的特性,除開了他的技術特性,為什麼不談技術特性,無論是類線程還是語法糖,在工程方面可能有點加分,架構層面沒什麼大的影響。真正在架構上加分的是Golang處於一個中間位置。

你可以看到知乎最近三個月增強了多媒體方面的內容,而你不要忘記,google的一個golang重要應用就是youtube。而且Golang是很典型的hybrid lang,一方面現有技術轉去Go,不會造成太大的重構壓力,一方面保留將來二次轉換的可能性,如果有更重的應用要求,還可以轉更重。

不過,照我看,他們的招聘內容裡面還少了一條,應該再要些集成經驗的人,根據我粗淺的使用經驗,知乎的集成做的不是很好,我很懷疑,知乎內部技術團隊是否有一個完整全面的integration governance landscape diagram(中文有什麼對應術語?)


點贊,python 寫起來相對 go 來說還是過於啰嗦了。


推薦閱讀:

如何理解Tornado中的協程模塊(gen.coroutine)?
知乎為什麼要選擇用Tornado做為web開發框架,非同步非阻塞模式在此起到了作用?
請問如何處理tornado模板和angular.js的 {{ }} 表達式衝突問題?

TAG:知乎 | 程序員 | Python | Tornado | Go語言 |