Go 開發關鍵技術指南 | 為什麼你要選擇 GO?(內含超全知識大圖)
作者 | 楊成立(忘籬) 阿里巴巴高階技術專家
關注 “阿里巴巴雲原生” 公眾號,回覆 Go 即可檢視清晰知識大圖!
導讀:從問題本身出發,不侷限於 Go 語言,探討伺服器中常常遇到的問題,最後回到 Go 如何解決這些問題,為大家提供 Go 開發的關鍵技術指南。我們將以系列文章的形式推出《Go 開發的關鍵技術指南》,共有 4 篇文章,本文為第 1 篇。
Go 開發指南大圖
Overview
該指南主要討論了伺服器領域常見的併發問題,也涉及到了工程化相關的問題,還整理了 C 背景程式設計師對於 Go 的 GC 以及效能的疑問,探討了 Go 的錯誤處理和型別系統最佳實踐,以及依賴管理的難處、介面設計的正交性,當然也包含我們在伺服器開發中對於 Go 實踐的總結,有時候也會對一些有趣的問題做深度的挖掘,列出了 Go 重要的事件和資料集合,以及 Go2 的進展和思考。
以下是各個章節以及簡介:
- About the Name:為何 Go 有時候也叫 Golang?
- Why Go:為何要選擇 Go 作為伺服器開發的語言?是衝動?還是騷動?
- Milestones:Go 的重要里程碑和事件,當年吹的那些牛逼,都實現了哪些?
- GC:Go 的 GC 靠譜嗎?Twitter 說相當的靠譜,有圖有真相。
- Could Not Recover:君可知,有什麼 panic 是無法 recover 的?包括超過系統執行緒限制,以及 map 的競爭寫。當然一般都能 recover,比如 Slice 越界、nil 指標、除零、寫關閉的 chan 等。
- Declaration Syntax:為何 Go 語言的宣告語法是那樣的?C 語言的宣告語法又是怎樣的?是拍的大腿,還是拍的腦袋?
- Errors:為什麼 Go2 的草稿 3 箇中有 2 個是關於錯誤處理的?好的錯誤處理應該怎麼做?錯誤和異常機制的差別是什麼?錯誤處理和日誌如何配合?
- Logger:為什麼標準庫的 Logger 是完全不夠用的?怎麼做日誌切割和輪轉?怎麼在混成一坨的伺服器日誌中找到某個連線的日誌?甚至連線中的流的日誌?怎麼做到簡潔又夠用?
- Type System:什麼是物件導向的 SOLID 原則?為何 Go 更符合 SOLID?為何介面組合比繼承多型更具有正交性?Go 型別系統如何做到 looser、organic、decoupled、independent and therefore scalable?
- Orthogonal:一般軟體中如果出現數學,要麼真的牛逼,要麼就是裝逼。正交性這個數學概念在 Go 中頻繁出現,是神仙還是妖怪?為何介面設計要考慮正交性?
- Modules:如何避免依賴地獄 (Dependency Hell)?小小的版本號為何會帶來大災難?Go 為什麼推出了 GOPATH、Vendor 還要搞 module 和 vgo?新建了 16 個倉庫做測試,碰到了 9 個坑,搞清楚了 gopath 和 vendor 如何遷移?以及 vgo with vendor 如何使用(畢竟生產環境不能每次都去外網下載)?
- Concurrency:伺服器中的併發處理難在哪裡?為什麼說 Go 併發處理優勢佔領了雲端計算開發語言市場?什麼是 C10K、C10M 問題?
- Context:如何管理 goroutine 的取消、超時和關聯取消?為何 Go1.7 專門將 context 放到了標準庫?context 如何使用以及問題在哪裡?
- Engineering:Go 在工程化上的優勢是什麼?為什麼說 Go 是一門面向工程的語言?覆蓋率要到多少比較合適?什麼叫程式碼可測性?為什麼良好的庫必須先寫 Example?
- Go2 Transition:Go2 會像 Python3 不相容 Python2 那樣作嗎?C 和 C++ 的語言演進可以有什麼不同的收穫?Go2 怎麼思考語言升級的問題?
- Documents:Go 官網的重要文件分類,本屌絲讀了四遍了,推薦閱讀。
- SRS:Go 在流媒體伺服器中的使用。
About the Name
The Go Programming Language 到底是該叫 GO 還是 GOLANG?Google 搜 Why Go is called Golang
能搜到幾篇經典帖子。
Rob Pike 在 Twitter 上特意說明是 Go,可以看這個 The language is called Go:
Neither. The language is called Go, not Golang. http://golang.org is just the the web site address, not the name of the language.
在另外一個地方也說明了是 Go,可以看這個 The name of our language is go:
The name of our language is Go
Ruby is called Ruby, not Rubylang.
Python is called Python, not Pythonlang.
C is called C, not Clang. No. Wait. That was a bad example.
Go is called Go, not Golang.
Yes, yes, I know all about the searching and meta tags. Sure, whatever,
but that doesn't change the fact that the name of the language is Go.
Thank you for your consideration.
這裡舉了各種例子說明為何不加 lang 的字尾,當然有個典型的語言是加的,就是 Erlang
。於是就有回覆說 “Erlang Erlang, Let's just call it Er.”
那麼為什麼大多時候 Go 和 Golang 都很常用呢?在 Why is the Go programming language usually called Golang 中說的比較清楚:
It’s because “go domain” has been registered by Walt Disney and so Go creators couldn’t use it.
So, they have decided to use golang for the domain name. Then the rest came.
Also, it’s harder to search things on search engines just using the word Go. Although, Rob Pike is
against this idea but I disagree. Most of the time, for the correct results you need to search for
golang.
It’s just Go, not golang but it sticked to it.
講個笑話先,用百度搜下為何 Go 叫做 Golang,一大片都是類似本文的雞湯煲,告訴你為何 Go 才是天地間最合適你的語言,當然本文要成為雞湯煲中的戰鬥煲,告訴你全家都應該選擇 Go 語言。
為何 Go 語言名字是 Go,但是經常說成是 Golang 呢?有以下理由:
- go.org 被註冊了,正在賣,也不貴才 1698 萬。所以 Go 只能用 golang.org;
- 想要搜點啥資訊時,如果搜 go 太寬泛了,特別是 go 還沒有這麼多使用者時,搜 golang 能更精確的找到答案。
為什麼在名字上要這麼糾結呢?嗯嗯,不糾結,讓我們開始幹雞湯吧。
Why Go?
考慮一個商用的快速發展的業務後端伺服器,最重要的是什麼?當然是穩定性了,如果崩潰可能會造成使用者服務中斷,崩潰的問題在 C/C++ 伺服器中幾乎是必然的:
- 穩定是一種假象;
想象一個 C 伺服器,一般不會重頭碼所有的程式碼,會從一個開源版本開始,或者從一些網路和執行緒庫開始,然後不斷改進和完善。由於業務前期並不複雜,上線也沒有發現問題,這時候可以說 C 伺服器是穩定的嗎?當然不是,只是 Bug 沒有觸發而已,所有崩潰的 Bug 幾乎都不是本次釋出導致的。野指標和越界是 C 伺服器中最難搞定的狼人,這些狼人還喜歡玩潛伏。
- 穩定是短暫的,不穩定是必然和長期的;
一般業務會突飛猛進,特別是越偏上層的業務,需要後端處理的邏輯就越多,至於 UTest 和測試一般只存在於傳說中,隨著業務的發展,潛伏的狼人越來越多,甚至開源的庫和伺服器中的狼人也開始出來作妖。夜路走多了,總會碰到鬼,碰到鬼了怎麼辦?當然是遇鬼殺鬼了,還能被它嚇尿不成,所以就反思解決 Bug,費了老勁、又白了幾根頭髮,終於迎來短暫安寧,然後繼續寫 Bug。
- 最普遍的問題還是記憶體問題導致崩潰,一般就是野指標和越界;
空指標問題相對很容易查,除零之類的典型錯誤也容易處理。最完善的解決辦法,就是實現 GC,讓指標總是有效,無效後再釋放,越界時能檢測到,這樣容易解決問題;其實 Go 早期的版本就和這個很類似了,要實現帶 GC 的 C 的同學,可以參考下 Go 的實現。
- 線上的 CPU 和記憶體的問題,一般不方便使用工具檢視,而線上的問題有時候很難在本地重現。
如何能直接獲取線上的 Profile 資料,需要程式本身支援。比如提供 HTTP API 能獲取到 Profile 資料,關鍵是如何採集這些資料。
Go 的使命願景和價值觀:
Go is an open source programming language that makes it easy to build simple, reliable, and efficient software.
Go is a concurrent open source programming language developed at Google. Combines native compilation and static types with a lightweight dynamic feel. Fast, fun, and productive.>
Go is an attempt to make programmers more productive. The first goal is to make a better language to meet the challenges of scalable concurrency. The larger goal is to make a better environment to meet the challenges of scalable software development, software worked on and used by many people, with limited coordination between them, and maintained for years.
Go 語言的關鍵字:
- 執行效能高: Statically typed. Native code generation (compiled). Efficiency. Fast development cycle.
- 碼農不苦逼: Memory safe. Garbage collected. Safety.
- 雲端計算專享: Native concurrency support. Concurrency. Scalability.
- 工程師思維: Composition via interfaces. Excellent standard library. Great tools.
參考 The Path to Go1: What is Go? 和 Another Go at Language Design。
參考 > Go: a simple programming environment。
Go 是面向軟體工程的語言,Go 在工程上的思考可以讀 Go at Google: Language Design in the Service of Software Engineering 和 Less is exponentially more。Go 最初是解決 Google 遇到的大規模系統和計算的問題,這些問題如今被稱為雲端計算,參考 Go, Open Source, Community。
GITHUT上顯示 Go 的專案和 PR 一直在上升,如下圖所示。
2014 雲端計算行業中使用 Go 的有:Docker, Kubernetes, Packer, Serf, InfluxDB, Cloud Foundry’s gorouter and CLI, CoreOS’s etcd and fleet, Vitess | YouTube’s tooling for MySQL scaling, Canonical’s Juju (rewritten in Go), Mozilla’s Heka, A Go interface to OpenStack Swift, Heroku’s Force.com and hk CLIs, Apcera’s NATS and gnatsd。
2018 年全球使用 Go 的公司數目有:US(329), Japan(79), Brazil(52), India(49), Indonesia(45), China(32), UK(32), Germany(28), Israel(24), France(17), Netherlands(16), Canada (15), Thailand(14), Turkey(14), Spain(12), Poland(11), Australia(9), Russia(9), Iran(8), Sweden(7), Korea(South)(6), Switzerland(6), Ukraine(5)。
參考 Go as the emerging language of cloud infrastructure、The RedMonk Programming Language Rankings: June 2018,還有 GoUsers 以及 Success Stories。
參考 > "Go: 90% Perfect, 100% of the time" -bradfitz, 2014。參考 > Nine years of Go: Go Contributors,社群貢獻的程式碼比例。
我們一起看看這些 Go 牛逼的特性,詳細分析每個點,雖然不能涵蓋所有的點,對於常用的 Go 的特性我們做一次探討和分析。
Milestones
接下來看一下有關 Go 的重要事件:
- 2019 年 9 月,Go1.13 釋出。增強了 modules,新增了環境變數 GOPRIVATE 和 GOSUMDB,GOPROXY 支援多個,支援了 ErrorWraping;
- 2019 年 2 月,Go1.12 釋出,支援了 TLS1.3,改進了 modules,優化執行時和標準庫;
- 2018 年 8 月,Go1.11 釋出,實驗性支援 modules,實驗性支援 WebAssembly;
- 2018 年 2 月,Go1.10 釋出,go tool 快取編譯,編譯加速,很多細微的改進;
- 2018 年 1 月,Hello, 中國! 及 中國站映象上線,大陸可以訪問官網資源;
- 2017 年 8 月,Go1.9 釋出,支援 Type Alias、sync.Map,使用場景參考 slides,time 保持單增避免時間測量問題;
- 2017 年 2 月,Go1.8 釋出,顯著的效能提升,GC 延遲降低到了 10us 到 100us,支援 HTTP/2 Push,HTTP Server 支援 Shutdown,
sort.Slice
使排序使用更簡單; - 2016 年 8 月,Go1.7 釋出,支援了 Context,Context 在 K8s 和 Docker 中都有應用,新的編譯演算法減少 20%-30% 的二進位制尺寸;
- 2016 年 2 月,Go1.6 釋出,支援 HTTP/2,HTTPS 時會預設開啟 HTTP/2,正式支援 vendor;
- 2015 年 8 月,Go1.5 釋出,完全用 Go 代替了 C 程式碼,完全重新設計和重新實現 GC,支援 internal 的 package,實驗性支援 vendor,GOMAXPROCS 預設為 CPU 個數;
- 2014 年 12 月,Go1.4 釋出,支援 Android,從 Mecurial 遷移到了 Git,從 GoogleCode 遷移到了 Github: golang/go,大部分 runtime 的程式碼從 C 改成了 Go,
for
支援三種迭代寫法; - 2014 年 6 月,Go1.3 釋出,支援了 FreeBSD、Plan9、Solaris 等系統;
- 2013 年 12 月,Go1.2 釋出,新增收集覆蓋率工具 coverage,限制了最高執行緒數 ThreadLimit;
- 2013 年 5 月,Go1.1 釋出,主要是包含效能優化,新增
Data Race Detector
等; - 2012 年 3 月,Go1.0 釋出,包含了基本的語言元素比如 rune、error、map,標準庫包括 bufio、crypto、flag、http、net、os、regexp、runtime、unsafe、url、encoding 等;
- 2009 年 11 月, Google 宣佈要開發一門新語言,既要開源,又有 Python 的好處,還要有 C/C++ 的效能。GO 是 BSD 的 License,大部分 GO 的專案都是 BSD 或 MIT 或 Apache 等商業友好的協議。
“阿里巴巴雲原生關注微服務、Serverless、容器、Service Mesh 等技術領域、聚焦雲原生流行技術趨勢、雲原生大規模的落地實踐,做最懂雲原生開發者的技術圈。”
- 加微信實戰群請加微信(註明:實戰群):gocnio
相關文章
- Go 開發關鍵技術指南 | 為什麼你要選擇 GO?(內含超全知識大圖)Go
- Go 開發關鍵技術指南 | 敢問路在何方?(內含超全知識大圖)Go
- Go 開發關鍵技術指南 | Go 面向失敗程式設計 (內含超全知識大圖)Go程式設計
- Go 開發關鍵技術指南 | 帶著伺服器程式設計金剛經走進 2020 年 (內含超全知識大圖)Go伺服器程式設計
- Go 開發關鍵技術指南 | 帶著伺服器程式設計金剛經走進 2020 年(內含超全知識大圖)Go伺服器程式設計
- 老闆:你為什麼要選擇 Vue?Vue
- 為什麼要選擇SQL?SQL
- 為什麼要選擇Python進行Web開發?PythonWeb
- 一文讀懂分散式架構知識體系(內含超全核心知識大圖)分散式架構
- go 知識圖譜Go
- Google 大佬們為什麼要開發 Go 這門新語言?Go
- Go 為什麼要設計 iota 常量?Go
- 為什麼企業要選擇低程式碼開發平臺?
- 技術團隊為什麼要開源?
- Web前端技術知識:為什麼要進行網站重構呢?Web前端網站
- [精選] 為什麼要選擇Go語言作為PHP的黃金組合?而不是Java或PythonGoPHPJavaPython
- 為什麼要學習Go語言呢?Go
- 為什麼在Go語言中要慎用interface{}Go
- 為什麼很多公司都轉型go語言開發?Go語言能做什麼Go
- 為什麼要選擇Python進行Web開發?記得收藏!PythonWeb
- 為什麼那麼多人要學習go語言?go語言有什麼特點?Go
- 什麼是技術債,為什麼要還技術債?
- 為什麼爬蟲要選擇住宅代理?爬蟲
- 為什麼開發人員從Java轉GoJavaGo
- 【知識分享】跨境業務為什麼選擇海外伺服器伺服器
- 如何熟悉一個系統?(內含知識大圖)
- 我為什麼要學技術
- 企業建站為什麼要選擇雲伺服器?這些常識你要知道!伺服器
- 【建議收藏】Go語言關鍵知識點總結Go
- 我為什麼會選擇Vim來開發Go專案及Vim IDE安裝配置和操作GoIDE
- 小馬識途營銷顧問:為什麼做百度SEO要選擇全網優化?優化
- go金融系統開發中的關鍵知識點:確保穩定、安全和高效Go
- 為什麼要選擇學習Web前端開發?無法反駁的4大理由!Web前端
- 為什麼要選擇蘋果企業簽名?蘋果
- 為什麼要選擇分散式資料庫?分散式資料庫
- 為什麼要選擇電話機器人?機器人
- 為什麼要選擇代理來進行抓取?
- 關於「內隱知識」:你說不清楚為什麼某作品會紅