這是一個建立於 的文章,其中的資訊可能已經有所發展或是發生改變。作者|許式偉編輯|小智2007 年 9 月 20 日,關於設計一門全新語言的討論正式開始,這門全新的語言,就是後來的 Go。時至今日,Go 語言已經發布到 1.9 版本,走過了整整十年的曆程。在這十年間,Go 語言兩奪 TIOBE 年度語言大獎(2009/2016),許多初創公司在早期使用 Go 進行開發,包括現在的雲端運算巨頭 Docker,也由此催生出了 Kubernetes 這樣的項目。在大洋彼岸的中國,Google Trends 顯示 Go 的異常火爆更讓 Go 語言之父感到震驚。而這一切,跟一位名叫許式偉的技術人密不可分。
Go 語言剛剛度過了它的十周年紀念日。而要說我與 Go 的緣分,也同樣始於十年前(2007 年)。這十年,是 Go 成長的十年,同樣也是我成長的十年。
2007 年 2 月,我建立了金山實驗室,主攻分布式儲存方向。這是我職業生涯至關重要的一個轉折點。此前我已經做了 7 年的 WPS Office 辦公套件的研發。這對我有兩個重要的挑戰:一個是角色轉換上的,從做軟體研發的架構師到做業務的產品經理;一個是技術領域變化上的,從單機的案頭軟體開發到分布式的後端伺服器開發。
我第一個面臨的問題是技術選型。幾乎沒有作任何糾結,我們選擇了 Java 作為主體的開發語言。作為初入後端開發領域的團隊來說,這隻是一個從務實角度出發的選擇。但 TrustNo1 在程式員雜誌發表的《一場茶杯裡的風暴》一文讓我認識了 Erlang 語言,並深深被 Erlang 的編程思想所打動。我意識到這種編程思想將會極大釋放服務端編程的生產力。為了推動服務端最佳實務的探索,也為了進一步推動更多人瞭解和研究 Erlang,我發起了 ECUG 社區。ECUG 到現在已經十年。這十年我們風雨無阻,每年年底都會舉行一場 ECUG Con 大會,和來自各行各業的技術大拿們齊聚一堂,大家一起分享這一年來服務端開發的實踐心得。
儘管我們選擇了 Java,但是隨後我們也做了小範圍使用 Erlang 進行開發的嘗試。在 2008 年我們啟動了一個用 Erlang 來編寫儲存系統(極簡版)的業餘項目。這次的嘗試讓我對 Erlang 有了進一步的判斷:儘管 Erlang 的編程思想很好,但是 Erlang 語言本身並不適合大型的工程項目。
到了 2009 年 3 月,也就是我加入盛大創新院重啟分布式儲存項目時,我面臨了第二次技術選型。這一次我選了最難的一條路:用 C++ 來開發。這是一條艱苦的路。促使我做出這一選擇的最大原因是,我很希望能夠製造一個新輪子,它應該既有 Erlang 編程思想的優勢,又可以克服 Erlang 語言的劣勢。如果這事能夠幹成,它將是一件偉大的創舉,所有的服務端開發人員都將受益於此。於是,在心懷滿腔熱血之下,一個名為 CERL 的項目誕生了。在我們儲存的第一個版本期間,實際上我們花費在 CERL 庫的時間遠超過了做儲存本身,無論從代碼量還是花費的精力來說都是如此。
CERL 項目經曆了 2 個大的版本。CERL 1.0 完全遵循 Erlang 的編程思想,主要編程範式如下:
可以啟動任意多的進程(這裡進程是抽象的概念,實現上是纖程 / 協程),進程數上限只受限於記憶體大小。
每個進程有進程郵箱,相互發訊息通過進程郵箱。
訊息分同步訊息和非同步訊息,同步訊息會阻塞等待對方返回訊息。
網路伺服器是單進程模型(就是大家理解的單執行緒模式),一次只處理一個訊息。
沒有鎖。
…
基於 CERL 1.0 的編程模型,我們實踐中發現了這樣一些問題:
在網路伺服器 A、B 相互給對方發送同步訊息時會發生“死結”。因為雙方可能都正在處理訊息中而無法及時響應,這種“死結”最終表現為逾時(但是實際上逾時更可怕,是伺服器效能的殺手)。
解決“死結”的方法是把同步訊息改為非同步,但是這對編程複雜性帶來很大的影響,程式語義變得晦澀。本質上,這是回到了傳統的非同步編程模型,放棄了 Erlang 編程模型最大的優勢。
“沒有鎖”的假設代價過高:在網路伺服器的單個處理回應時間較長(儲存服務必然如此)時,必然希望啟動獨立的進程來響應單個請求。但是各個處理請求的進程之間需要共用網路伺服器的狀態,這就意味著需要有鎖(除非網路伺服器是無狀態的,但是很不倖存儲伺服器必然是帶狀態的)。要麼放棄效能序列化地處理請求,要麼有鎖 —“沒有鎖”,想說愛你不容易。
…
在發現“死結”問題後,我們立刻對我們整個編程模型進行了反思,決定重構整個編程模型,修改後的 CERL2.0 要點如下:
可以啟動任意多的進程(這裡進程是抽象的概念,實現上是纖程 / 協程),進程數上限只受限於記憶體大小。
沒有進程郵箱。
進程之間只有同步訊息(要發送非同步訊息,用啟動一個新的進程並發送同步訊息來達到同樣的效果)。
網路伺服器是多進程模型,每個請求都由一個獨立的進程來處理。
有鎖。
兩個版本的編程模型的關鍵差異在於拒絕鎖還是拒絕非同步訊息。CERL 1.0(也就是 Erlang 編程模型)中拒絕鎖,而 CERL 2.0 拒絕非同步訊息。基於 CERL 2.0 我們實現了分布式儲存的第二版、第三版。事實證明,完全杜絕了非同步訊息這個概念後,這個版本的伺服器編程模型心智負擔小了很多。
然後,如大家所知,後來 Go 語言就發布了。我們團隊一看,在伺服器編程模型這一點上,CERL 2.0 和 Go 語言居然一模一樣(包括所有細節上的決策)。有一次團隊聚餐談起這事時,道哥(李道兵)說了一句:我們趕緊把 CERL 開源吧,不然等 Go 流行起來它就沒機會了。我還真和創新院院長陳大年談了 CERL 開源的事情,大年說:沒問題,你發個郵件申請吧,留個憑證。然而我最終沒有發出這封郵件。在嘗試用 Go 寫了一周的代碼後,我心裡已經有了結論:我並不打算讓 CERL 面世。因為有人已經把它的目標完成了,而且遠超預期。
於是,2011 年 6 月,我們離開盛大創新院創辦七牛雲的時候,我面臨了第三次技術選型。這一次,我很堅決地選擇了 Go 語言。為此我還專門給團隊發了一封郵件,郵件中有一段是這麼說的:
在創業過程中我們會面臨很多選擇,也會有很多選擇後來會被證明是錯的,但是今天我可以確定的是,選擇 Go 將會成為我們最正確的選擇。
在選擇了 Go 語言後,考慮到 Go 仍然是一門十分小眾的語言,我們開始有意識地培養 Go 中國社區。為了讓更多人能夠知道 Go,加入 Go 的行列,我們做了很多工作。我們啟動了《Go 語言編程》一書的編寫工作,並最終和 Go 1.0 版本同步發布。2012 年 2 月,我首次在公開場合說:Go 會超過 C、Java,成為最流行的語言。這一年我到處宣講,做了不下十場的 Go 語言講座,平均每個月有一場。講得最多的一個 PPT 是《Go,Next C》這篇,它基本上算我對 Go 的革命性到底在哪裡的一個總結。對於一個初創公司來說,為一個並不屬於自己業務的技術這麼花時間去宣傳,有些人可能會覺得比較不可理解。但是實際上有三個理由支撐我們這麼做:
Go 真的是一門革命性的語言,它的流行將對產業發展具重大意義。
Go 仍然是一門小眾語言,而我們不止要招 Go 程式員,更重要的是要說服他們相信 Go 語言是有遠大前景的專業技能方向。
七牛的使用者是程式員,我們需要建立在使用者心目中的專家形象。
七牛雲的起步第一個業務是雲端儲存,我們選擇了完全用 Go 來實現我們的儲存系統。這是全球第一個用 Go 寫的雲端儲存,也是第一個用 Go 寫的雲端服務。而到了 2014 年,在我們決定進入大資料領域時,我們再一次面臨技術選型問題。坦白說,我們還是糾結了一段時間的。從生態來說,選擇 Java,或者某種 JVM 平台的語言(比如 Scala)有非常顯著的優勢。尤其對於我們大資料業務的負責人陳超這個 Scala 的狂熱粉絲(八卦一下:陳超的網路 id 是 CrazyJVM),選擇 JVM 平台似乎更加是毋庸置疑的選擇。那麼我們糾結什麼呢?我們認為未來 Go 會佔領整個基礎設施領域,而大資料無疑是其中極具關鍵意義的一個領域。所以面向現在做選型,還是面向未來做選型,這是一個問題。
說到這裡我提一個有意思的細節。在陳超剛加入七牛的時候,我對他說:“不管未來你會用什麼語言,但是進入七牛必須要會寫 Go。”於是他被我逼著寫了一個月的 Go 代碼。一個月後我問他感覺如何,他說:“能夠理解為什麼你推薦 Go 了,寫了 Go 代碼後不想回去寫 Scala 代碼。”不久之後,在他啟動 Pandora 大資料平台項目時,就碰到了我說的選型問題。在做了非常細緻的思考之後,他決定用 Go 做 Pandora。這對我來說是一個意料之外的決策。因為我自己在這個事情上並沒有傾向性,而陳超我覺得他很可能還是會優先選 Scala。就在最近(國慶節前)某次聊天中,陳超回顧起這件事,總結了一下他為什麼選擇了 Go:極低的學習成本,極低的心智負擔。如果用 Scala,新人入職要培訓,還要擔心寫出糟糕的 Scala 代碼。但是用 Go 新人不培訓直接上崗,幾次 Code Review 完後基本就能夠知道怎麼寫出品質不錯的 Go 代碼了。
十年過去,Go 已經不再是一門小眾語言。越來越多人在用 Go,喜歡上 Go。不記得是什麼時候了,但是某一天通過 Google Trends 搜尋 golang 發現全世界 Go 最火的地區是在中國時,那一刻真的很開心。
下一個十年會怎樣?我知道有一些人很期望 Go 語言特性的迭代。但是如果你抱有這種想法可能會失望,因為下一個十年 Go 不會發生太大的變化。對遠期需求變化的預測和把控能力,是 Go 的最大魅力之一。這一點上能夠和 Go 相比的是 C 語言(C 語言不同版本的規範差異極少),但因為 Go 要解決的問題更多,做到這一點實際上也更難。下一個十年 Go 仍然會繼續深耕服務端開發的生態,同時積極探索其他潛在的應用市場。
延展閱讀
在 QCon 2015 上海站上,許式偉曾經做過《Go 語言發展狀況》的主題分享。對於 Go 語言,他提到過三個預測:
第一個預測,我最早在 2012 年新浪微博裡提過,Go 語言 10 年內一定會超過 C 和 Java,變成熱門排行榜第一的語言。今天大家可能會略相信,但在 2012 年的時候沒有多少人會相信,即使今天講出來,絕大部分人都會覺得太早,畢竟它還沒有排進前五。
第二個預測,Go 語言將在兩年內製霸雲端運算領域。
第三個預測,Go 將統治下一個 10 年。(來自於 Deferpanic 創始人 Lan Eyberg)。
更多相關資訊,請點擊以下標題閱讀:
《Go 將統治下一個 10 年?Go 語言發展現狀分析》
延展實踐
文中提到的 Scala 狂魔陳超老師和他啟動的 Pandora 大資料平台項目,在這次 QCon 上海站上,我們有幸邀請到陳超老師分享其中的的技術選型,組件設計、系統調優及架構演化過程,歡迎點擊【閱讀原文】探索更多技術分享。
除此之外,Google、Uber、Paypal、LinkedIn、Airbnb 等頂尖技術專家也會前來分享前沿實踐經驗。大會報名最後一周,下一個高效能更便捷的前瞻技術請鎖定 QCon 上海 2017。有問題歡迎聯絡購票經理 Hanna,電話:15110019061,:qcon-0410。
作者介紹
許式偉,七牛雲 CEO。ECUG 社區發起人,國內 Go 語言實踐圈子公認的 Go 語言專家,並著有《Go 語言編程》。超過 10 年互連網從業經驗,曾在金山、盛大事技術研究方面的工作,是 WPS2005 的首席架構師。2011 年創辦七牛雲。
今日薦文
點擊下方圖片即可閱讀
許式偉:編程的意義就是讓世界變得有趣一些