Go 開發關鍵技術指南 | 爲何你要選擇 GO?(內含超全知識大圖)

導讀:從問題自己出發,不侷限於 Go 語言,探討服務器中經常遇到的問題,最後回到 Go 如何解決這些問題,爲你們提供 Go 開發的關鍵技術指南。咱們將以系列文章的形式推出《Go 開發的關鍵技術指南》,共有 4 篇文章,本文爲第 1 篇。

Go 開發指南大圖

Overview

該指南主要討論了服務器領域常見的併發問題,也涉及到了工程化相關的問題,還整理了 C 背景程序員對於 Go 的 GC 以及性能的疑問,探討了 Go 的錯誤處理和類型系統最佳實踐,以及依賴管理的難處、接口設計的正交性,固然也包含咱們在服務器開發中對於 Go 實踐的總結,有時候也會對一些有趣的問題作深度的挖掘,列出了 Go 重要的事件和資料集合,以及 Go2 的進展和思考。html

如下是各個章節以及簡介:git

  • 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:github

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 gogolang

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.」web

那麼爲何大多時候 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 語言。docker

爲什麼 Go 語言名字是 Go,可是常常說成是 Golang 呢?有如下理由:後端

  1. go.org 被註冊了,正在賣,也不貴才 1698 萬。因此 Go 只能用 golang.org;
  2. 想要搜點啥信息時,若是搜 go 太寬泛了,特別是 go 尚未這麼多用戶時,搜 golang 能更精確的找到答案。

爲何在名字上要這麼糾結呢?嗯嗯,不糾結,讓咱們開始幹雞湯吧。api

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 的有:DockerKubernetes, 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 infrastructureThe 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、Plan九、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 等商業友好的協議。

本文做者:楊成立(忘籬)

閱讀原文

本文爲阿里雲內容,未經容許不得轉載。

相關文章
相關標籤/搜索