第二屆 Gopher China 大會

傅小黑發表於2016-10-09

又一次,和同事去參加 GopherChina 2016 大會,瞭解 Go 語言相關的最新動態。和一年前不同,Go 語言已經受到許多企業青睞。一些知名企業開始使用 Go 語言開發。因而,本屆大會更多的內容注重在 Go 實現的業務場景和架構上。

Go 與 高併發服務

Go 語言的 goroutine 特性,非常適合開發高併發網路服務。大會有幾個題目聊起相關的內容。

百度前端接入團隊分享了《Go在百度BFE的應用》。相關的內容其實在InfoQ有過分享。百度的服務體量太過巨大(日均千億),程式碼優化手段 + Go的版本更新 對服務整體的提升作用不大,只能用特殊的措施 ———— 車輪大戰。關閉 runtime 的GC,由程式碼根據目前程式的執行情況判斷是否手動 runtime.GC()。以 master-worker的模式輪換正在服務和正在GC的程式。這種架構估計只有百度這種規模才用得上吧。但是私下的交流來說,小夥伴還是覺得 nginx + C 模組更適合。況且BFE之前那套也就是C寫的,有足夠的技術實力。

對比的來看是,吳小偉(skoo)的《Go在阿里雲CDN系統的應用》。阿里 CDN 的網路接入系統還是 C 語言寫的。CDN 的日誌系統、排程系統和重新整理系統是 Go 寫的。這些業務對 Go 語言的 GC 不敏感,加上 Go 比 C 更簡潔的語法特性,更快的開發效率,開發周圍系統是很適合的。這裡可以看到,同樣是大流量系統,思考的角度也有不同。順便說一下,skoo 是比較早研究 Go 語言的技術大神之一,部落格有一些關於 Go 核心原理的文章。

Go 與 分散式服務

大會裡的幾個 Go 開發的分散式服務涉及資料庫,儲存,搜尋。

劉奇的《Go在分散式資料庫中的應用》主要是分享他主導開發的 TiDB 分散式資料庫。TiDB 是基於 kv 儲存的 SQL 分散式資料庫。想一下,必然有 KV 儲存層,KV 到 SQL 的轉換,SQL 連線協議,以及分散式相關的模組。首先,使用 rust 開發了 TiKV 分散式 kv 儲存系統,類似 HBase。然後使用 Go 開發相容各種 kv 儲存的 API 層,SQL 處理層, MySQL 協議層 和 分散式管理。TiDB 最核心的部分是 Placement Driver 分散式管理模組,負責路由資料儲存的region,儲存region的schema和region擴容複製及刪除。關於資料庫開發我沒有什麼經驗,只能聽聽參考思路。

毛劍的《Go在資料儲存上面的應用》參考 Facebook 的 Haystack paper 實現自己的小檔案儲存系統 bfs。儲存系統一般的結構包括目錄路由和儲存節點。目錄路由負責定位資源實際的儲存位置。儲存節點負責實際資料儲存過程處理,比如合併。bfs 再加上了對外統一的 API 層 ———— 暴露簡單的操作介面遮蔽細節, pitchfork 心跳監控層 ———— 保證節點可用性。毛大很細節的講了各個模組的實現,及儲存資料的流動過程、副本複製和節點災備的問題。內容充足有條理,聽的比較好而且可以參考學習的細節較多。

陳輝聊了一下《Go 與人工智慧》。題目很大,主要的內容是分詞演算法、搜尋引擎、抓取工具和機器學習。算是一般大資料研究需要的基礎智慧技術。wukong 搜尋 和 sego 分詞已經很早以前放出了。wukong 搜尋是一個搜尋引擎架子,有很好的定製化能力。除了基本的分詞、索引和排序,還可以自己新增演算法進行篩選。wukong搜尋目前是全資料都載入到記憶體的。希望以後可以更方便的支援實時資料落地和讀取,減小記憶體佔用。

Go 與 容器

Docker 是 Go 的明星產品,但是已經形成自己的生態。單純聊 Docker,就有很大一系列內容。大會的兩個題目主要聊的內容是 Go 在 Docker 叢集中的作為外在工具的角色。

小米高步雙《Go在小米商城運維平臺的應用與實踐》很大的篇幅在說使用 Docker 搭建了 MAE(Mall App Engine) 叢集滿足小米商城的業務需求。Go 語言開發了 Docker 中的模組,叢集 Router 和 Monitor。Docker 的 API 對 Go 友善。使用 Go 開發管理工具更方便控制 Docker 叢集。演講中提到了 fasthttp,比 net/http 效能更高。我以前有篇 文章 分析 fasthttp,它並不適合做 HTTP 長連線服務。另外還提及了一下 TCP 的 Multiplex Connection,令我想起了 HTTP2。

Daocloud 的孫巨集亮對 Docker 有深刻的研究。更多的說 Daocloud 關於公共 Docker 叢集的架構,關於 Go 的內容聊的比較少。孫老師對於 Go 操作程式和系統命令的能力很滿意,使用 Go 開發了 Daocloud 很多的輔助功能工具,但是可惜沒有深入介紹。

另一個容器化的明星是 CoreOS。大會上鄧洪超的《Go在CoreOS分散式系統的效能除錯和優化》很熱情的介紹基於 CoreOS 的容器隔離體系。我並不熟悉 CoreOS 體系,這次的內容權當是科普。容器化的世界不僅僅是 Docker 的世界。去看看更多的技術開眼界也是極好的。

Go 與 Web

Go 的 HTTP 包已經足夠實現 Web API 服務。但是 html/template 包的詭異語法對實現繁多複雜頁面的 Web 站點並不是很好的選擇。米嘉的演講《Go build web》利用程式碼生成來滿足對應的需求。路由部分繼承 Gin 和 Goji 的中介軟體思路,資料庫操作部分使用go generate命令自動生成結構體操作的程式碼,再開發了一個工具做start-kit的boilerplate做前端資源、熱更新等的支援,這幾個部分組成了完善的 Go Web 技術棧工具。其實目前很多新手是從 Web 方面開始學習 Go 語言。熟練使用或者自己參照實現類似的技術工具,還是很不靠譜的。如果真要學習,還可以去看看 goa 這個利用 Go 做 DSL 的程式碼生成工具。

Go 與 移動開發

沈晟沈老闆為我們帶來了《Golang在移動客戶端開發中的應用》。沈老闆在比較多的是說團隊對 [gomobile] 的探索和嘗試。目前 Go 參與 mobile 開發的方式是將一些演算法庫或者邏輯庫編譯成 c-archive 或者 .so 嵌入到 app 中,並不是代替 Obj-C 或者 Java 作為主力開發的角色。介紹的內容還都是概念性的演示,還沒有實際案例。GopherCon India 有幾個關於 mobile 演講比這次更加激進一些,有興趣的同學可以去 看看。

Go 的細節

Go 開發組的兩位外國友人在更加細緻的尺度上描述了 Go 語言的一些功能和特性。

Marcel van Lohuizen 主要介紹了 《I18n and L13n for Go using x/text》,golang.org/x/text 庫的功能和計劃。我並不熟悉文字編碼方面的知識,但是看作者在各種字符集之間操作正確處理本地化差異的時候,所做的工作,感到由衷的敬佩。針對某個庫某一些功能做了細緻入微的研究,是國外技術人員很優秀的品質。而且演講的內容豐富,很多細節很有意思,我覺得很有趣很好玩,從來沒想過本地化和國際化還有這麼多門道。

Dave Cheney 是 GB 版本管理工具的作者,Go 語言的 linker 的主要維護者,對 Go 語言細節有很深的認識。這次《Writing High Performance Go》從程式碼書寫、除錯、測試的層面幫助使用者提升技巧。比如如何避免 string 和 []byte 轉換時的記憶體拷貝的影響,預想建立適當長度的 slice 避免擴容浪費,多使用 bufio 來操作位元組流,思考和明確程式碼中 goroutine 的生命週期,使用佇列池等方式控制 goroutine 的數量等。Slide 中列舉了很多需要考慮的細節和使用注意,非常的贊。而且 slide 是使用 Go 的 present 工具生成的,一邊展示一邊直接操作程式碼,非常的直觀。而且為了介紹 net/http/pprof 竟然在 present 工具開啟了 pprof 為我們展示,表現力超讚。

這裡可以發現很多時候我們不僅僅是需要面對各種複雜業務的規劃和架構能力,還需要對使用的工具細緻入微的操控能力。

Go 的持續整合

Grab 的 趙暢 的 《Golang專案的測試,持續整合以及部署策略》也是我覺得非常讚的一組內容。不僅描述 Go 的開發,測試,持續整合和部署,而且介紹創業公司對各種不同領域的雲服務的應用。使用 gometalinter 檢查程式碼規範和程式碼質量,使用 testify 簡化測試邏輯,從 Travis CI 到自己搭建 Jenkins 的整合服務演進之路,還有 Scalyr 日誌分析,Slack 團隊專案管理。國外的團隊對各種第三方的輔助工具有非常充分的利用,而國內創業企業還不願意去嘗試這些方式。

技術沙龍

第一天的大會後晚上舉行了技術沙龍,有 Go vs Rust 和 Docker vs VM 的兩場大戰。

Go 和 Rust 的戰鬥集中在程式碼風格和社群文化上。Go 和 Rust 雖然都是近些年發展的語言,但是很多的思考看得出現在的語言的發展。 Go 秉承降低心智負擔的基本原則,以最簡單直接以至於簡陋的方式來實現,比如 if err != nil 到處都是。這樣逼迫使用者仔細思考每一步的問題,把error認為正常邏輯裡的一環去深入考慮。而 Rust 使用 try(fn()) 和 fn()? 更優雅的處理錯誤也是大多數程式設計師希望的事情。誰也不願意反覆的寫if err的語句。而且 try 這種方式也是借鑑其他語言的成功經驗的。可以認為大多數不是心智太低,不需要像 Go 強制讓你仔仔細細思考清楚的,還是更願意接受稍微複雜了一點的 try 方式。Go 的 error 是 value 不是錯誤,這個哲學使它將 error 和其他正常值等價考慮,才有這樣繁瑣了一些的操作。try 的使用意味著這裡在操作一個特殊的值 error,讓大家注意。到底該如何對待 error,估計還是會有持久的論戰。

Docker 容器化是新興的分散式系統部署方案,VM 部署已經是成熟的解決方案。使用新興的方案未必會帶來足夠好的效益,也是大家考慮擔憂的一點。我覺得 Docker 適應微服務架構,重點除了更清晰的架構劃分,更細粒度的資源控制外,還有就是可描述的架構模型。Docker 容器體系的編排和排程工具,就是對大規模應用有了一種可以描述的方式,就是編排和排程配置。這對於以後如何控制大規模的叢集有重要意義。

很多大神們

BetaGo 和 毛劍 之前就認識,只是他倆坐下來就是在聊妹子,我呵呵呵呵呵。Asta謝作為主辦者,還是一直忙前忙後沒有停歇。劉奇 大神光亮的頭頂非常的好辨認,郝林比我看到的照片裡感覺更胖了哈哈。

我只是個普通的程式設計師,並不是大神。參加大會還是瞭解和學習,幫助自己做好工作,我就滿足了。

相關文章