Go開發(fā)關(guān)鍵技術(shù)指南:Concurrency & Control

Concurrency

早在十八年前的1999年匾浪,千兆網(wǎng)卡還是一個(gè)新玩意兒皇帮,想當(dāng)年有吉比特帶寬卻只能支持10K客戶端,還是個(gè)值得研究的問題蛋辈,畢竟Nginx在2009年才出來属拾,在這之前大家還在內(nèi)核折騰過HTTP服務(wù)器,服務(wù)器領(lǐng)域還在討論如何解決C10K問題,C10K中文翻譯在這里捌年。讀這個(gè)文章瓢娜,感覺進(jìn)入了繁忙服務(wù)器工廠的車間,成千上萬錯(cuò)綜復(fù)雜的電纜交織在一起礼预,甚至還有古老的驚群(thundering herd)問題眠砾,驚群像遠(yuǎn)古狼人一樣就算是在21世紀(jì)還是偶然能聽到它的傳說。現(xiàn)在大家討論的都是如何支持C10M托酸,也就是千萬級并發(fā)的問題褒颈。

并發(fā),無疑是服務(wù)器領(lǐng)域永遠(yuǎn)無法逃避的話題励堡,是服務(wù)器軟件工程師的基本能力谷丸。Go的撒手锏之一無疑就是并發(fā)處理,如果要從Go眾多優(yōu)秀的特性中挑一個(gè)应结,那就是并發(fā)和工程化刨疼,如果只能選一個(gè)的話,那就是并發(fā)的支持鹅龄。大規(guī)模軟件揩慕,或者云計(jì)算,很大一部分都是服務(wù)器編程扮休,服務(wù)器要處理的幾個(gè)基本問題:并發(fā)迎卤、集群、容災(zāi)玷坠、兼容蜗搔、運(yùn)維,這些問題都可以因?yàn)镚o的并發(fā)特性得到改善八堡,按照《人月神話》的觀點(diǎn)樟凄,并發(fā)無疑是服務(wù)器領(lǐng)域的固有復(fù)雜度(Essential Complexity)之一。Go之所以能迅速占領(lǐng)云計(jì)算的市場兄渺,Go的并發(fā)機(jī)制是至關(guān)重要的不同。

借用《人月神話》中關(guān)于固有復(fù)雜度(Essential Complexity)的概念,能比較清晰的說明并發(fā)問題溶耘。就算沒有讀過這本書二拐,也肯定聽過軟件開發(fā)“沒有銀彈”,要保持軟件的“概念完整性”凳兵,Brooks作為硬件和軟件的雙重專家和出色的教育家始終活躍在計(jì)算機(jī)舞臺上百新,在計(jì)算機(jī)技術(shù)的諸多領(lǐng)域中都作出了巨大的貢獻(xiàn),在1964年(33歲)領(lǐng)導(dǎo)了IBM System/360IBM OS/360的研發(fā)庐扫,于1993年(62歲)獲得馮諾依曼獎(jiǎng)饭望,并于1999年(68歲)獲得圖靈獎(jiǎng)仗哨,在2010年(79歲)獲得虛擬現(xiàn)實(shí)(VR)的獎(jiǎng)項(xiàng)IEEE Virtual Reality Career Award (2010)

在軟件領(lǐng)域铅辞,很少能有像《人月神話》一樣具有深遠(yuǎn)影響力和暢銷不衰的著作厌漂。Brooks博士為人們管理復(fù)雜項(xiàng)目提供了具有洞察力的見解,既有很多發(fā)人深省的觀點(diǎn)斟珊,又有大量軟件工程的實(shí)踐苇倡。本書內(nèi)容來自Brooks博士在IBM公司System/360家族和OS/360中的項(xiàng)目管理經(jīng)驗(yàn),該項(xiàng)目堪稱軟件開發(fā)項(xiàng)目管理的典范囤踩。該書英文原版一經(jīng)面世旨椒,即引起業(yè)內(nèi)人士的強(qiáng)烈反響,后又譯為德堵漱、法综慎、日、俄勤庐、中示惊、韓等多種文字,全球銷售數(shù)百萬冊愉镰。確立了其在行業(yè)內(nèi)的經(jīng)典地位米罚。

Brooks是我最崇拜的人,有理論有實(shí)踐岛杀,懂硬件懂軟件,致力于大規(guī)模軟件(當(dāng)初還沒有云計(jì)算)系統(tǒng)崭孤,足夠(長達(dá)十年甚至二十年)的預(yù)見性类嗤,孜孜不倦奮斗不止,強(qiáng)烈推薦軟件工程師讀《人月神話》辨宠。

短暫的廣告回來遗锣,繼續(xù)討論并發(fā)(Concurrency)的問題,要理解并發(fā)的問題就必須從了解并發(fā)問題本身,以及并發(fā)處理模型開始。2012年我在當(dāng)時(shí)中國最大的CDN公司藍(lán)汛設(shè)計(jì)和開發(fā)流媒體服務(wù)器時(shí)涩嚣,學(xué)習(xí)了以高并發(fā)聞名的NGINX的并發(fā)處理機(jī)制EDSM(Event-Driven State Machine Architecture)逞刷,自己也照著這套機(jī)制實(shí)現(xiàn)了一個(gè)流媒體服務(wù)器,和HTTP的Request-Response模型不同侦镇,流媒體的協(xié)議比如RTMP非常復(fù)雜中間狀態(tài)非常多,特別是在做到集群Edge時(shí)和上游服務(wù)器的交互會(huì)導(dǎo)致系統(tǒng)的狀態(tài)機(jī)翻倍,當(dāng)時(shí)請教了公司的北美研發(fā)中心的架構(gòu)師Michael叶组,Michael推薦我用一個(gè)叫做ST(StateThreads)的技術(shù)解決這個(gè)問題,ST實(shí)際上使用setjmp和longjmp實(shí)現(xiàn)了用戶態(tài)線程或者叫協(xié)程历造,協(xié)程和goroutine是類似的都是在用戶空間的輕量級線程甩十,當(dāng)時(shí)我本沒有懂為什么要用一個(gè)完全不懂的協(xié)程的東西船庇,后來我花時(shí)間了解了ST后豁然開朗,原來服務(wù)器的并發(fā)處理有幾種典型的并發(fā)模型侣监,流媒體服務(wù)器中超級復(fù)雜的狀態(tài)機(jī)鸭轮,也廣泛存在于各種服務(wù)器領(lǐng)域中,屬于這個(gè)復(fù)雜協(xié)議服務(wù)器領(lǐng)域不可Remove的一種固有復(fù)雜度(Essential Complexity)橄霉。

我翻譯了ST(StateThreads)總結(jié)的并發(fā)處理模型高性能窃爷、高并發(fā)、高擴(kuò)展性和可讀性的網(wǎng)絡(luò)服務(wù)器架構(gòu):State Threads for Internet Applications酪劫,這篇文章也是理解Go并發(fā)處理的關(guān)鍵吞鸭,本質(zhì)上ST就是C語言的協(xié)程庫(騰訊微信也開源過一個(gè)libco協(xié)程庫),而goroutine是Go語言級別的實(shí)現(xiàn)覆糟,本質(zhì)上他們解決的領(lǐng)域問題是一樣的刻剥,當(dāng)然goroutine會(huì)更廣泛一些,ST只是一個(gè)網(wǎng)絡(luò)庫滩字。我們一起看看并發(fā)的本質(zhì)目標(biāo)造虏,一起看圖說話吧,先從并發(fā)相關(guān)的性能和伸縮性問題說起:

image.png
  • 橫軸是客戶端的數(shù)目麦箍,縱軸是吞吐率也就是正常提供服務(wù)需要能吐出的數(shù)據(jù)漓藕,比如1000個(gè)客戶端在觀看500Kbps碼率的視頻時(shí),意味著每個(gè)客戶端每秒需要500Kb的數(shù)據(jù)挟裂,那么服務(wù)器需要每秒吐出500*1000Kb=500Mb的數(shù)據(jù)才能正常提供服務(wù)享钞,如果服務(wù)器因?yàn)樾阅軉栴}CPU跑滿了都無法達(dá)到500Mbps的吞吐率,客戶端必定就會(huì)開始卡頓诀蓉。
  • 圖中黑色的線是客戶端要求的最低吞吐率栗竖,假設(shè)每個(gè)客戶端都是一樣的,那么黑色的線就是一條斜率固定的直線渠啤,也就是客戶端越多吞吐率就越多狐肢,基本上和客戶端數(shù)目成正比。比如1個(gè)客戶端需要500Kbps的吞吐率沥曹,1000個(gè)就是500Mbps吞吐率份名。
  • 圖中藍(lán)色的實(shí)線,是服務(wù)器實(shí)際能達(dá)到的吞吐率妓美。在客戶端比較少時(shí)僵腺,由于CPU空閑,服務(wù)器(如果有需要)能夠以超過客戶端要求的最低吞吐率給數(shù)據(jù)壶栋,比如點(diǎn)播服務(wù)器的場景想邦,客戶端看500Kbps碼率的點(diǎn)播視頻,每秒最少需要500Kb的數(shù)據(jù)委刘,那么服務(wù)器可以以800Kbps的吞吐率給客戶端數(shù)據(jù)丧没,這樣客戶端自然不會(huì)卡頓鹰椒,客戶端會(huì)將數(shù)據(jù)保存在自己的緩沖區(qū),只是如果用戶放棄播放這個(gè)視頻時(shí)會(huì)導(dǎo)致緩存的數(shù)據(jù)浪費(fèi)呕童。
  • 圖中藍(lán)色實(shí)線會(huì)有個(gè)天花板漆际,也就是服務(wù)器在給定的CPU資源下的最高吞吐率,比如某個(gè)版本的服務(wù)器再4CPU下由于性能問題只能達(dá)到1Gbps的吞吐率夺饲,那么黑線和藍(lán)線的交叉點(diǎn)奸汇,就是這個(gè)服務(wù)器能正常服務(wù)的最多客戶端比如2000個(gè)。理論上如果超過這個(gè)最大值比如10K個(gè)往声,服務(wù)器吞吐率還是保持在最大吞吐率比如1Gbps擂找,但是由于客戶端的數(shù)目持續(xù)增加需要繼續(xù)消耗系統(tǒng)資源,比如10K個(gè)FD和線程的切換會(huì)搶占用于網(wǎng)絡(luò)收發(fā)的CPU時(shí)間浩销,那么就會(huì)出現(xiàn)藍(lán)色虛線贯涎,也就是超負(fù)載運(yùn)行的服務(wù)器,吞吐率會(huì)降低慢洋,導(dǎo)致服務(wù)器無法正常服務(wù)已經(jīng)連接的客戶端塘雳。
  • 負(fù)載伸縮性(Load Scalability)就是指黑線和藍(lán)線的交叉點(diǎn),系統(tǒng)的負(fù)載能力如何普筹,或者說是否并發(fā)模型能否盡可能的將CPU用在網(wǎng)絡(luò)吞吐上败明,而不是程序切換上,比如多進(jìn)程的服務(wù)器太防,負(fù)載伸縮性就非常差妻顶,有些空閑的客戶端也會(huì)Fork一個(gè)進(jìn)程服務(wù),這無疑是浪費(fèi)了CPU資源的蜒车。同時(shí)多進(jìn)程的系統(tǒng)伸縮性會(huì)很好讳嘱,增加CPU資源時(shí)吞吐率基本上都是線性的。
  • 系統(tǒng)伸縮性(System Scalability)是指吞吐率是否隨系統(tǒng)資源線性增加醇王,比如新增一倍的CPU呢燥,是否吞吐率能翻倍崭添。圖中綠線寓娩,就是增加了一倍的CPU,那么好的系統(tǒng)伸縮性應(yīng)該系統(tǒng)的吞吐率也要增加一倍呼渣。比如多線程程序中棘伴,由于要對競爭資源加鎖或者多線程同步,增加的CPU并不能完全用于吞吐率屁置,多線程模型的系統(tǒng)伸縮性就不如多進(jìn)程模型焊夸。

并發(fā)的模型包括幾種,總結(jié)Existing Architectures如下表:

Arch Load Scalability System Scalability Robust Complexity Example
Multi-Process Poor Good Great Simple Apache1.x
Multi-Threaded Good Poor Poor Complex Tomcat, FMS/AMS
Event-Driven
State Machine
Great Great Good Very
Complex
Nginx, CRTMPD
StateThreads Great Great Good Simple SRS, Go
  • MP(Multi-Process)多進(jìn)程模型:每個(gè)連接Fork一個(gè)進(jìn)程服務(wù)蓝角。系統(tǒng)的魯棒性非常好阱穗,連接彼此隔離互不影響饭冬,就算有進(jìn)程掛掉也不會(huì)影響其他連接。負(fù)載伸縮性(Load Scalability)非常差(Poor)揪阶,系統(tǒng)在大量進(jìn)程之間切換的開銷太大昌抠,無法將盡可能多的CPU時(shí)間使用在網(wǎng)絡(luò)吞吐上,比如4CPU的服務(wù)器啟動(dòng)1000個(gè)繁忙的進(jìn)程基本上無法正常服務(wù)鲁僚。系統(tǒng)伸縮性(System Scalability)非常好炊苫,增加CPU時(shí)一般系統(tǒng)吞吐率是線性增長的。目前比較少見純粹的多進(jìn)程服務(wù)器了冰沙,特別是一個(gè)連接一個(gè)進(jìn)程這種侨艾。雖然性能很低,但是系統(tǒng)復(fù)雜度低(Simple)拓挥,進(jìn)程很獨(dú)立唠梨,不需要處理鎖或者狀態(tài)。
  • MT(Multi-Threaded)多線程模型:有的是每個(gè)連接一個(gè)線程撞叽,改進(jìn)型的是按照職責(zé)分連接姻成,比如讀寫分離的線程,幾個(gè)線程讀愿棋,幾個(gè)線程寫科展。系統(tǒng)的魯棒性不好(Poor),一個(gè)連接或線程出現(xiàn)問題糠雨,影響其他的線程才睹,彼此互相影響。負(fù)載伸縮性(Load Scalability)比較好(Good)甘邀,線程比進(jìn)程輕量一些琅攘,多個(gè)用戶線程對應(yīng)一個(gè)內(nèi)核線程,但出現(xiàn)被阻塞時(shí)性能會(huì)顯著降低松邪,變成和多進(jìn)程一樣的情況坞琴。系統(tǒng)伸縮性(System Scalability)比較差(Poor),主要是因?yàn)榫€程同步逗抑,就算用戶空間避免鎖剧辐,在內(nèi)核層一樣也避免不了;增加CPU時(shí)邮府,一般在多線程上會(huì)有損耗荧关,并不能獲得多進(jìn)程那種幾乎線性的吞吐率增加。多線程的復(fù)雜度(Complex)也比較高褂傀,主要是并發(fā)和鎖引入的問題忍啤。
  • EDSM(Event-Driven State Machine)事件驅(qū)動(dòng)的狀態(tài)機(jī)。比如select/poll/epoll仙辟,一般是單進(jìn)程單線程同波,這樣可以避免多進(jìn)程的鎖問題鳄梅,為了避免單程的系統(tǒng)伸縮問題可以使用多進(jìn)程單線程,比如NGINX就是這種方式未檩。系統(tǒng)魯棒性比較好(Good)卫枝,一個(gè)進(jìn)程服務(wù)一部分的客戶端,有一定的隔離讹挎。負(fù)載伸縮性(Load Scalability)非常好(Great)校赤,沒有進(jìn)程或線程的切換,用戶空間的開銷也非常少筒溃,CPU幾乎都可以用在網(wǎng)絡(luò)吞吐上马篮。系統(tǒng)伸縮性(System Scalability)很好,多進(jìn)程擴(kuò)展時(shí)幾乎是線性增加吞吐率怜奖。雖然效率很高浑测,但是復(fù)雜度也非常高(Very Complex),需要維護(hù)復(fù)雜的狀態(tài)機(jī)歪玲,特別是兩個(gè)耦合的狀態(tài)機(jī)迁央,比如客戶端服務(wù)的狀態(tài)機(jī)和回源的狀態(tài)機(jī)。
  • ST(StateThreads)協(xié)程模型滥崩。在EDSM的基礎(chǔ)上岖圈,解決了復(fù)雜狀態(tài)機(jī)的問題,從堆開辟協(xié)程的棧钙皮,將狀態(tài)保存在棧中蜂科,在異步IO等待(EAGAIN)時(shí),主動(dòng)切換(setjmp/longjmp)到其他的協(xié)程完成IO短条。也就是ST是綜合了EDSM和MT的優(yōu)勢导匣,不過ST的線程是用戶空間線程而不是系統(tǒng)線程,用戶空間線程也會(huì)有調(diào)度的開銷茸时,不過比系統(tǒng)的開銷要小很多贡定。協(xié)程的調(diào)度開銷,和EDSM的大循環(huán)的開銷差不多可都,需要循環(huán)每個(gè)激活的客戶端缓待,逐個(gè)處理。而ST的主要問題汹粤,在于平臺的適配命斧,由于glibc的setjmp/longjmp是加密的無法修改SP棧指針田晚,所以ST自己實(shí)現(xiàn)了這個(gè)邏輯嘱兼,對于不同的平臺就需要自己適配,目前Linux支持比較好贤徒,Windows不支持芹壕,另外這個(gè)庫也不在維護(hù)有些坑只能繞過去汇四,比較偏僻使用和維護(hù)者都很少,比如ST Patch修復(fù)了一些問題踢涌。

我將Go也放在了ST這種模型中通孽,雖然它是多線程+協(xié)程,和SRS不同是多進(jìn)程+協(xié)程(SRS本身是單進(jìn)程+協(xié)程可以擴(kuò)展為多進(jìn)程+協(xié)程)睁壁。

從并發(fā)模型看Go的goroutine背苦,Go有ST的優(yōu)勢,沒有ST的劣勢潘明,這就是Go的并發(fā)模型厲害的地方了行剂。當(dāng)然Go的多線程是有一定開銷的,并沒有純粹多進(jìn)程單線程那么高的負(fù)載伸縮性钳降,在活躍的連接過多時(shí)厚宰,可能會(huì)激活多個(gè)物理線程,導(dǎo)致性能降低遂填。也就是Go的性能會(huì)比ST或EDSM要差铲觉,而這些性能用來交換了系統(tǒng)的維護(hù)性,個(gè)人認(rèn)為很值得吓坚。除了goroutine撵幽,另外非常關(guān)鍵的就是chan。Go的并發(fā)實(shí)際上并非只有g(shù)oroutine礁击,而是goroutine+chan并齐,chan用來在多個(gè)goroutine之間同步。實(shí)際上在這兩個(gè)機(jī)制上客税,還有標(biāo)準(zhǔn)庫中的context况褪,這三板斧是Go的并發(fā)的撒手锏。

由于Go是多線程的丝蹭,關(guān)于多線程或協(xié)程同步,除了chan也提供了Mutex坪蚁,其實(shí)這兩個(gè)都是可以用的奔穿,而且有時(shí)候比較適合用chan而不是用Mutex,有時(shí)候適合用Mutex不適合用chan敏晤,參考Mutex or Channel巫橄。

Channel Mutex
passing ownership of data,<br />distributing units of work,<br /> communicating async results caches,<br />state

特別提醒:不要懼怕使用Mutex,不要什么都用chan茵典,千里馬可以一日千里卻不能抓老鼠湘换,HelloKitty跑不了多快抓老鼠卻比千里馬強(qiáng)。

Context

實(shí)際上goroutine的管理统阿,在真正高可用的程序中是非常必要的彩倚,我們一般會(huì)需要支持幾種gorotine的控制方式:

  1. 錯(cuò)誤處理:比如底層函數(shù)發(fā)生錯(cuò)誤后,我們是忽略并告警(比如只是某個(gè)連接受到影響)扶平,還是選擇中斷整個(gè)服務(wù)(比如LICENSE到期)帆离。
  2. 用戶取消:比如升級時(shí),我們需要主動(dòng)的遷移新的請求到新的服務(wù)结澄,或者取消一些長時(shí)間運(yùn)行的goroutine哥谷,這就叫熱升級。
  3. 超時(shí)關(guān)閉:比如請求的最大請求時(shí)長是30秒麻献,那么超過這個(gè)時(shí)間们妥,我們就應(yīng)該取消請求。一般客戶端的服務(wù)響應(yīng)是有時(shí)間限制的勉吻。
  4. 關(guān)聯(lián)取消:比如客戶端請求服務(wù)器监婶,服務(wù)器還要請求后端很多服務(wù),如果中間客戶端關(guān)閉了連接齿桃,服務(wù)器應(yīng)該中止惑惶,而不是繼續(xù)請求完所有的后端服務(wù)。

而goroutine的管理短纵,最開始只有chan和sync带污,需要自己手動(dòng)實(shí)現(xiàn)goroutine的生命周期管理,參考Go Concurrency Patterns: Timing out, moving onGo Concurrency Patterns: Context香到,這些都是goroutine的并發(fā)范式鱼冀。

直接使用原始的組件管理goroutine太繁瑣了报破,后來在一些大型項(xiàng)目中出現(xiàn)了context這些庫,并且Go1.7之后變成了標(biāo)準(zhǔn)庫的一部分雷绢。具體參考GOLANG使用Context管理關(guān)聯(lián)goroutine以及GOLANG使用Context實(shí)現(xiàn)傳值、超時(shí)和取消理卑。

Context也有問題:

  1. 支持Cancel翘紊、Timeout和Value,這些都是擴(kuò)張Context樹的節(jié)點(diǎn)藐唠。Cancel和Timeout在子樹取消時(shí)會(huì)刪除子樹帆疟,不會(huì)一直膨脹;Value沒有提供刪除的函數(shù)宇立,如果他們有公共的根節(jié)點(diǎn)踪宠,會(huì)導(dǎo)致這個(gè)Context樹越來越龐大;所以Value類型的Context應(yīng)該掛在Cancel的Context樹下面妈嘹,這樣在取消時(shí)GC會(huì)回收柳琢。
  2. 會(huì)導(dǎo)致接口不一致或者奇怪,比如io.Reader其實(shí)第一個(gè)參數(shù)應(yīng)該是context润脸,比如Read(Context, []byte)函數(shù)柬脸。或者提供兩套接口毙驯,一種帶Contex倒堕,一種不帶Context。這個(gè)問題還蠻困擾人的爆价,一般在應(yīng)用程序中垦巴,推薦第一個(gè)參數(shù)是Context。
  3. 注意Context樹铭段,如果因?yàn)镃losure導(dǎo)致樹越來越深骤宣,會(huì)有調(diào)用棧的性能問題。比如十萬個(gè)長鏈序愚,會(huì)導(dǎo)致CPU占用500%左右涯雅。

備注:關(guān)于對Context的批評,可以參考Context should go away for Go 2展运,作者覺得在標(biāo)準(zhǔn)庫中加context作為第一個(gè)參數(shù)不能理解活逆,比如Read(ctx context.Context等。

Links

由于簡書限制了文章字?jǐn)?shù)拗胜,只好分成不同章節(jié):

  • Overview 為何Go有時(shí)候也叫Golang?為何要選擇Go作為服務(wù)器開發(fā)的語言蔗候?是沖動(dòng)?還是騷動(dòng)埂软?Go的重要里程碑和事件锈遥,當(dāng)年吹的那些牛逼纫事,都實(shí)現(xiàn)了哪些?
  • Could Not Recover 君可知所灸,有什么panic是無法recover的丽惶?包括超過系統(tǒng)線程限制,以及map的競爭寫爬立。當(dāng)然一般都能recover钾唬,比如Slice越界、nil指針侠驯、除零抡秆、寫關(guān)閉的chan等。
  • Errors 為什么Go2的草稿3個(gè)有2個(gè)是關(guān)于錯(cuò)誤處理的吟策?好的錯(cuò)誤處理應(yīng)該怎么做儒士?錯(cuò)誤和異常機(jī)制的差別是什么?錯(cuò)誤處理和日志如何配合檩坚?
  • Logger 為什么標(biāo)準(zhǔn)庫的Logger是完全不夠用的着撩?怎么做日志切割和輪轉(zhuǎn)?怎么在混成一坨的服務(wù)器日志中找到某個(gè)連接的日志匾委?甚至連接中的流的日志睹酌?怎么做到簡潔又夠用?
  • Interfaces 什么是面向?qū)ο蟮腟OLID原則剩檀?為何Go更符合SOLID憋沿?為何接口組合比繼承多態(tài)更具有正交性?Go類型系統(tǒng)如何做到looser, organic, decoupled, independent, and therefore scalable沪猴?一般軟件中如果出現(xiàn)數(shù)學(xué)辐啄,要么真的牛逼要么裝逼。正交性這個(gè)數(shù)學(xué)概念在Go中頻繁出現(xiàn)运嗜,是神仙還是妖怪壶辜?為何接口設(shè)計(jì)要考慮正交性?
  • Modules 如何避免依賴地獄(Dependency Hell)担租?小小的版本號為何會(huì)帶來大災(zāi)難砸民?Go為什么推出了GOPATH、Vendor還要搞module和vgo奋救?新建了16個(gè)倉庫做測試岭参,碰到了9個(gè)坑,搞清楚了gopath和vendor如何遷移尝艘,以及vgo with vendor如何使用(畢竟生產(chǎn)環(huán)境不能每次都去外網(wǎng)下載)演侯。
  • Concurrency & Control 服務(wù)器中的并發(fā)處理難在哪里?為什么說Go并發(fā)處理優(yōu)勢占領(lǐng)了云計(jì)算開發(fā)語言市場背亥?什么是C10K秒际、C10M問題悬赏?如何管理goroutine的取消、超時(shí)和關(guān)聯(lián)取消娄徊?為何Go1.7專門將context放到了標(biāo)準(zhǔn)庫闽颇?context如何使用,以及問題在哪里寄锐?
  • Engineering Go在工程化上的優(yōu)勢是什么兵多?為什么說Go是一門面向工程的語言?覆蓋率要到多少比較合適锐峭?什么叫代碼可測性中鼠?為什么良好的庫必須先寫Example可婶?
  • Go2 Transition Go2會(huì)像Python3不兼容Python2那樣作嗎沿癞?C和C++的語言演進(jìn)可以有什么不同的收獲?Go2怎么思考語言升級的問題矛渴?
  • SRS & Others Go在流媒體服務(wù)器中的使用椎扬。Go的GC靠譜嗎?Twitter說相當(dāng)?shù)目孔V具温,有圖有真相蚕涤。為何Go的聲明語法是那樣?C的又是怎樣铣猩?是拍的大腿揖铜,還是拍的腦袋?
最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
禁止轉(zhuǎn)載达皿,如需轉(zhuǎn)載請通過簡信或評論聯(lián)系作者天吓。
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市峦椰,隨后出現(xiàn)的幾起案子龄寞,更是在濱河造成了極大的恐慌,老刑警劉巖汤功,帶你破解...
    沈念sama閱讀 218,036評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異色解,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)冒签,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,046評論 3 395
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來萧恕,“玉大人刚梭,你說我怎么就攤上這事朴读。” “怎么了走趋?”我有些...
    開封第一講書人閱讀 164,411評論 0 354
  • 文/不壞的土叔 我叫張陵衅金,是天一觀的道長簿煌。 經(jīng)常有香客問我氮唯,道長,這世上最難降的妖魔是什么姨伟? 我笑而不...
    開封第一講書人閱讀 58,622評論 1 293
  • 正文 為了忘掉前任惩琉,我火速辦了婚禮,結(jié)果婚禮上夺荒,老公的妹妹穿的比我還像新娘瞒渠。我一直安慰自己,他們只是感情好技扼,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,661評論 6 392
  • 文/花漫 我一把揭開白布伍玖。 她就那樣靜靜地躺著,像睡著了一般剿吻。 火紅的嫁衣襯著肌膚如雪窍箍。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 51,521評論 1 304
  • 那天丽旅,我揣著相機(jī)與錄音椰棘,去河邊找鬼。 笑死魔招,一個(gè)胖子當(dāng)著我的面吹牛晰搀,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播办斑,決...
    沈念sama閱讀 40,288評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼外恕,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了乡翅?” 一聲冷哼從身側(cè)響起鳞疲,我...
    開封第一講書人閱讀 39,200評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎蠕蚜,沒想到半個(gè)月后尚洽,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 45,644評論 1 314
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡靶累,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,837評論 3 336
  • 正文 我和宋清朗相戀三年腺毫,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了癣疟。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,953評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡潮酒,死狀恐怖睛挚,靈堂內(nèi)的尸體忽然破棺而出急黎,到底是詐尸還是另有隱情,我是刑警寧澤淤击,帶...
    沈念sama閱讀 35,673評論 5 346
  • 正文 年R本政府宣布污抬,位于F島的核電站壕吹,受9級特大地震影響删铃,放射性物質(zhì)發(fā)生泄漏猎唁。R本人自食惡果不足惜顷蟆,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,281評論 3 329
  • 文/蒙蒙 一逐纬、第九天 我趴在偏房一處隱蔽的房頂上張望削樊。 院中可真熱鬧,春花似錦甸箱、人聲如沸芍殖。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,889評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽变秦。三九已至框舔,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間樱溉,已是汗流浹背福贞。 一陣腳步聲響...
    開封第一講書人閱讀 33,011評論 1 269
  • 我被黑心中介騙來泰國打工挖帘, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留恋技,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,119評論 3 370
  • 正文 我出身青樓,卻偏偏與公主長得像薄辅,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子脱惰,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,901評論 2 355

推薦閱讀更多精彩內(nèi)容