Go 語言是谷歌 2009 年首次推出并在 2012 年正式發(fā)布的一種全新的編程語言,可以在不損失應(yīng)用程序性能的情況下降低代碼的復(fù)雜性。谷歌首席軟件工程師羅布派克(Rob Pike)說:七牛之所以開發(fā) Go,是因為過去10多年間軟件開發(fā)的難度令人沮喪。Google 對 Go 寄予厚望,其設(shè)計是讓軟件充分發(fā)揮多核心處理器同步多工的優(yōu)點,并可解決面向?qū)ο蟪绦蛟O(shè)計的麻煩。它具有現(xiàn)代的程序語言特色,如垃圾回收,幫助開發(fā)者處理瑣碎但重要的內(nèi)存管理問題。Go 的速度也非常快,幾乎和 C 或 C++ 程序一樣快,且能夠快速開發(fā)應(yīng)用程序。
最初去評估Go語言最重要的原因是,七牛沒有找到一門合適的語言。從云計算領(lǐng)域的主要技術(shù)方案看,最受歡迎的是C++和Java。七牛知道亞馬遜是用了Java。我個人嘗試Java做服務(wù)端開發(fā)是在2007年金山實驗,Java的風格比較拘束或嚴謹,與我推崇的編程風格不合,并且在分布式系統(tǒng)開發(fā)上沒有顯著的優(yōu)勢,所以才會關(guān)注Erlang(也因此有了ECUG社區(qū))、Go等小眾語言。在我評估完Go語言后,我認為它是云計算領(lǐng)域最合適的開發(fā)語言。
如果說到 Java 曾經(jīng)的流行,我們會聯(lián)想到 SSH(Struts + Spring + Hibernate);如果提到 Python,也會聯(lián)想到 Django;如果提到 Ruby,會聯(lián)想到 Ruby on Rails;如果提到 JavaScript,會聯(lián)想到 NodeJS;如果提到 PHP,更是一堆長江后浪推前浪前浪死在沙灘上的 Web 開發(fā)框架。這些編程語言社區(qū)的繁榮昌盛無一例外都和 Web 開發(fā)息息相關(guān),且最終沉淀下來的都是各種五花八門各有千秋的眾多 Web 開發(fā)框架??梢哉f,我們當前所面臨和 Web 開發(fā)的技術(shù)選型,從未有過如此的繁榮。繁榮的背后,襯托的是一個大江東流去不復(fù)還的 PC Web 時代。
穩(wěn)定性來說,云計算都是假設(shè)單機是可以宕機的,要在單機的不可靠下讓整個集群可靠(這種宕機甚至不為用戶所感知)。七牛并不擔心單個進程的穩(wěn)定性,哪怕Go程序每天會掛一次,對七牛而言,也是可以接受的。
Go語言入門門檻非常之低。有任何其他語言的背景,學習Go語言只需要一周的時間。**七牛面試從來不問你會不會Go語言。七牛關(guān)心的是開發(fā)者的能力與七牛業(yè)務(wù)的匹配度,比如他算法基礎(chǔ)如何、是否擅長網(wǎng)絡(luò)編程、是否適合創(chuàng)業(yè)(對事情的責任感)等等。
Go 語言的哪些特點最吸引人?
并發(fā)
Go 最大的特色就是在語言層面天生支持并發(fā),不需要像其他大多數(shù)編程語言那樣需要開發(fā)者自行實現(xiàn)或借助第三方類庫實現(xiàn)并發(fā)編程,Go 在語言級別支持的并發(fā)編程,其邏輯簡化得通俗易懂簡單好上手。
性能
不同于大多數(shù)腳本或解釋性的高階編程語言,用 Go 編寫的代碼直接了當編譯成機器碼高效執(zhí)行。
簡潔
25 個關(guān)鍵字即表達你能想到的所有招式,沒有也不需要有任何多余,想干啥事就 go 一下。
跨平臺
x86、AMD64 (x86_64)、ARM;Linux、Windows、Darwin (OSX)、FreeBSD、Android (計劃Go 1.4) 幾乎全平臺支持,真正做到一份源碼,隨處編譯,到處運行。
Go 語言都有哪些常見的應(yīng)用場景?
作為一個 Go 語言的重度用戶來看,當前除了不適合拿來造操作系統(tǒng)以外在操作系統(tǒng)之上應(yīng)用級的事情都能干。再更具體一點,比如說適用于這樣一些使用場景:
系統(tǒng)應(yīng)用
以前要用 C/C++ 做的系統(tǒng)應(yīng)用,現(xiàn)在都可以用 Go 來寫,事半功倍,而且 Go 完美包容 C 源代碼,兩者互相調(diào)用還可以混合編譯從而無縫集成。
網(wǎng)絡(luò)應(yīng)用
包含了常見的服務(wù)端編程比如 Web 和 API Service,以前用 PHP / Python / Ruby / Java 干的事情現(xiàn)在都可以用 Go 更加簡單清晰的來寫。再比如還可以拿來做一些 Proxy(代理)如網(wǎng)絡(luò)穿透軟件等,你懂的。
分布式系統(tǒng)
基于 Go 強大的系統(tǒng)編程加網(wǎng)絡(luò)編程,打造各種跨網(wǎng)絡(luò)的分布式系統(tǒng)服務(wù),Go 社區(qū)有不少和分布式系統(tǒng)相關(guān)的開源產(chǎn)物。
各種形態(tài)的存儲和數(shù)據(jù)庫應(yīng)用
比如 groupcache,influxdb 等。
客戶端應(yīng)用
包括帶界面的桌面軟件,以及后續(xù)可以想像的移動端應(yīng)用(比如對 Android 的支持)。
云服務(wù)(PaaS)
如基于 Go 打造的七牛云存儲(分布式對象存儲系統(tǒng)),比如基于 Go 編寫的 Docker(一款開源的容器虛擬化產(chǎn)物)。
Go 能做的事情,包含但不限于以上羅列的使用場景。
比如 Web 開發(fā)。大多數(shù)編程語言之上的 Web 開發(fā)框架都是遵照 MVC 的處理流程去開發(fā) Web 應(yīng)用:Model 部分封裝數(shù)據(jù),Controller 部分處理業(yè)務(wù)邏輯,View 部分植入變量填充模板頁面。而大部分 Web 框架關(guān)于 MVC 的三部分都是在 Server-side 處理,比如對 View 部分的處理都是在 Server-side 通過程序動態(tài)對模版變量求值后再拼接組裝成 HTML 頁面輸出給瀏覽器去呈現(xiàn)。而 Go 開發(fā) Web 應(yīng)用,并不依賴任何 Web 開發(fā)框架,用內(nèi)置的標準庫就可以輕而易舉地實現(xiàn):比如使用 net/http 標準庫就可以數(shù)行代碼構(gòu)建一個完整的 Web 骨架應(yīng)用;再比如,通過關(guān)鍵字 struct 封裝一個數(shù)據(jù)結(jié)構(gòu)就可以表達原本 MVC 框架中需要用厚重的 ORM (Object-Relational Mapping) 才能表達的那部分。大道至簡,這可以說是 Go 的哲學。在 View 這一層,Go 也有相應(yīng)標準庫提供支持,但更推薦的做法,是當下比較流行的 MVVM (Model-View-ViewModel):Server-side 只輸出 JSON,瀏覽器 DOM 作為 View 層,前端 JavaScript 充當 Contoller 部分;這樣,不僅減少了 Server-side 的資源消耗還有中間傳輸?shù)木W(wǎng)絡(luò)流量,而且前端可以更靈活和更豐富,后端也可以更輕盈和更高效,也更有利于項目的分工和協(xié)作。
Go 語言在七牛中都開發(fā)了些什么服務(wù)?在七牛的代碼量中,Go 語言使用占多少比例?
七牛主要使用 Go 開發(fā)了以下服務(wù)和工具:
分布式存儲系統(tǒng) ( Distributed Key/Value Storage)
數(shù)據(jù)處理服務(wù) (Data Processing)
網(wǎng)絡(luò)接口服務(wù) (RESTful API Service)
消息隊列服務(wù)(Message Queue Service)
日志處理系統(tǒng) (Log Service)
Web 網(wǎng)站 (不含前端 JavaScript)
CLI 命令行和 GUI 圖形界面工具
其他輔助工具
總的來講,Go 在七牛七牛的工程中代碼覆蓋率超過 90% 。還有 10% 不能覆蓋的原因是七牛給開發(fā)者自助使用的 Web 界面需要用 JavaScript 編程來實現(xiàn)酷炫的前端,以及七牛為開發(fā)者準備了多達超過 10 種編程語言的 SDK 。
我們再來看看 Go 在當下這個多核時代的作為。不得不說,Go 最大的特色就是在語言層面天然支持并發(fā),在 Go 程序里邊,你可以通過在一個函數(shù)調(diào)用前使用關(guān)鍵字 go 即可讓該函數(shù) func 運行成為一個獨立的 goroutine,goroutine 可以理解成一種比線程更加輕盈更省開銷的輕量級協(xié)程。Go 的并發(fā)模型就是通過系統(tǒng)的線程來多路派遣這些獨立函數(shù)的執(zhí)行,使得每個用關(guān)鍵字 go 執(zhí)行調(diào)用的函數(shù)可以運行成為一個單位協(xié)程。當⼀個協(xié)程阻塞的時候,調(diào)度器就會自動把其他協(xié)程安排到另外的線程中去執(zhí)行,從而實現(xiàn)程序的無等待并行化運行。且調(diào)度的開銷非常小,單核 CPU 調(diào)度的規(guī)模不下于每秒百萬次,這使得我們能夠創(chuàng)建大量的 goroutines,從而可以很輕松地編寫并發(fā)程序達到我們想要的目的。
同時,Go 在語言層面還引入了 channel 這一內(nèi)置類型來實現(xiàn)并發(fā)執(zhí)行體 goroutines 之間的消息傳遞,通信靠 channels 來傳遞消息。Go 遵循 CSP(Communicating sequential processes) 并發(fā)模型,通過通信來共享內(nèi)存而不是用共享內(nèi)存的方式進行通信。Go 的并發(fā)里邊沒有共享內(nèi)存,更沒有內(nèi)存鎖,這一切都有利于進行更為安全和簡單的并行程序編寫。