Concurrency
早在十八年前的1999年,千兆網(wǎng)卡還是一個(gè)新玩意兒,想當(dāng)年有吉比特帶寬卻只能支持10K客戶端,還是個(gè)值得研究的問(wèn)題,畢竟Nginx在2009年才出來(lái),在這之前大家還在內(nèi)核折騰過(guò)HTTP服務(wù)器,服務(wù)器領(lǐng)域還在討論如何解決C10K問(wèn)題,C10K中文翻譯在這里。讀這個(gè)文章,感覺(jué)進(jìn)入了繁忙服務(wù)器工廠的車(chē)間,成千上萬(wàn)錯(cuò)綜復(fù)雜的電纜交織在一起,甚至還有古老的驚群(thundering herd)問(wèn)題,驚群像遠(yuǎn)古狼人一樣就算是在21世紀(jì)還是偶然能聽(tīng)到它的傳說(shuō)?,F(xiàn)在大家討論的都是如何支持C10M,也就是千萬(wàn)級(jí)并發(fā)的問(wèn)題。
并發(fā),無(wú)疑是服務(wù)器領(lǐng)域永遠(yuǎn)無(wú)法逃避的話題,是服務(wù)器軟件工程師的基本能力。Go的撒手锏之一無(wú)疑就是并發(fā)處理,如果要從Go眾多優(yōu)秀的特性中挑一個(gè),那就是并發(fā)和工程化,如果只能選一個(gè)的話,那就是并發(fā)的支持。大規(guī)模軟件,或者云計(jì)算,很大一部分都是服務(wù)器編程,服務(wù)器要處理的幾個(gè)基本問(wèn)題:并發(fā)、集群、容災(zāi)、兼容、運(yùn)維,這些問(wèn)題都可以因?yàn)镚o的并發(fā)特性得到改善,按照《人月神話》的觀點(diǎn),并發(fā)無(wú)疑是服務(wù)器領(lǐng)域的固有復(fù)雜度(Essential Complexity)之一。Go之所以能迅速占領(lǐng)云計(jì)算的市場(chǎng),Go的并發(fā)機(jī)制是至關(guān)重要的。
借用《人月神話》中關(guān)于固有復(fù)雜度(Essential Complexity)的概念,能比較清晰的說(shuō)明并發(fā)問(wèn)題。就算沒(méi)有讀過(guò)這本書(shū),也肯定聽(tīng)過(guò)軟件開(kāi)發(fā)“沒(méi)有銀彈”,要保持軟件的“概念完整性”,Brooks作為硬件和軟件的雙重專家和出色的教育家始終活躍在計(jì)算機(jī)舞臺(tái)上,在計(jì)算機(jī)技術(shù)的諸多領(lǐng)域中都作出了巨大的貢獻(xiàn),在1964年(33歲)領(lǐng)導(dǎo)了IBM System/360和IBM 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)影響力和暢銷(xiāo)不衰的著作。Brooks博士為人們管理復(fù)雜項(xiàng)目提供了具有洞察力的見(jiàn)解,既有很多發(fā)人深省的觀點(diǎn),又有大量軟件工程的實(shí)踐。本書(shū)內(nèi)容來(lái)自Brooks博士在IBM公司System/360家族和OS/360中的項(xiàng)目管理經(jīng)驗(yàn),該項(xiàng)目堪稱軟件開(kāi)發(fā)項(xiàng)目管理的典范。該書(shū)英文原版一經(jīng)面世,即引起業(yè)內(nèi)人士的強(qiáng)烈反響,后又譯為德、法、日、俄、中、韓等多種文字,全球銷(xiāo)售數(shù)百萬(wàn)冊(cè)。確立了其在行業(yè)內(nèi)的經(jīng)典地位。
Brooks是我最崇拜的人,有理論有實(shí)踐,懂硬件懂軟件,致力于大規(guī)模軟件(當(dāng)初還沒(méi)有云計(jì)算)系統(tǒng),足夠(長(zhǎng)達(dá)十年甚至二十年)的預(yù)見(jiàn)性,孜孜不倦奮斗不止,強(qiáng)烈推薦軟件工程師讀《人月神話》。
短暫的廣告回來(lái),繼續(xù)討論并發(fā)(Concurrency)的問(wèn)題,要理解并發(fā)的問(wèn)題就必須從了解并發(fā)問(wèn)題本身,以及并發(fā)處理模型開(kāi)始。2012年我在當(dāng)時(shí)中國(guó)最大的CDN公司藍(lán)汛設(shè)計(jì)和開(kāi)發(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í)請(qǐng)教了公司的北美研發(fā)中心的架構(gòu)師Michael,Michael推薦我用一個(gè)叫做ST(StateThreads)的技術(shù)解決這個(gè)問(wèn)題,ST實(shí)際上使用setjmp和longjmp實(shí)現(xiàn)了用戶態(tài)線程或者叫協(xié)程,協(xié)程和goroutine是類似的都是在用戶空間的輕量級(jí)線程,當(dāng)時(shí)我本沒(méi)有懂為什么要用一個(gè)完全不懂的協(xié)程的東西,后來(lái)我花時(shí)間了解了ST后豁然開(kāi)朗,原來(lái)服務(wù)器的并發(fā)處理有幾種典型的并發(fā)模型,流媒體服務(wù)器中超級(jí)復(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語(yǔ)言的協(xié)程庫(kù)(騰訊微信也開(kāi)源過(guò)一個(gè)libco協(xié)程庫(kù)),而goroutine是Go語(yǔ)言級(jí)別的實(shí)現(xiàn),本質(zhì)上他們解決的領(lǐng)域問(wèn)題是一樣的,當(dāng)然goroutine會(huì)更廣泛一些,ST只是一個(gè)網(wǎng)絡(luò)庫(kù)。我們一起看看并發(fā)的本質(zhì)目標(biāo),一起看圖說(shuō)話吧,先從并發(fā)相關(guān)的性能和伸縮性問(wèn)題說(shuō)起:

- 橫軸是客戶端的數(shù)目,縱軸是吞吐率也就是正常提供服務(wù)需要能吐出的數(shù)據(jù),比如
1000個(gè)客戶端在觀看500Kbps碼率的視頻時(shí),意味著每個(gè)客戶端每秒需要500Kb的數(shù)據(jù),那么服務(wù)器需要每秒吐出500*1000Kb=500Mb的數(shù)據(jù)才能正常提供服務(wù),如果服務(wù)器因?yàn)樾阅軉?wèn)題CPU跑滿了都無(wú)法達(dá)到500Mbps的吞吐率,客戶端必定就會(huì)開(kāi)始卡頓。 - 圖中黑色的線是客戶端要求的最低吞吐率,假設(shè)每個(gè)客戶端都是一樣的,那么黑色的線就是一條斜率固定的直線,也就是客戶端越多吞吐率就越多,基本上和客戶端數(shù)目成正比。比如1個(gè)客戶端需要500Kbps的吞吐率,1000個(gè)就是500Mbps吞吐率。
- 圖中藍(lán)色的實(shí)線,是服務(wù)器實(shí)際能達(dá)到的吞吐率。在客戶端比較少時(shí),由于CPU空閑,服務(wù)器(如果有需要)能夠以超過(guò)客戶端要求的最低吞吐率給數(shù)據(jù),比如點(diǎn)播服務(wù)器的場(chǎng)景,客戶端看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下由于性能問(wèn)題只能達(dá)到1Gbps的吞吐率,那么黑線和藍(lán)線的交叉點(diǎn),就是這個(gè)服務(wù)器能正常服務(wù)的最多客戶端比如2000個(gè)。理論上如果超過(guò)這個(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ú)法正常服務(wù)已經(jīng)連接的客戶端。
- 負(fù)載伸縮性(Load Scalability)就是指黑線和藍(lán)線的交叉點(diǎn),系統(tǒng)的負(fù)載能力如何,或者說(shuō)是否并發(fā)模型能否盡可能的將CPU用在網(wǎng)絡(luò)吞吐上,而不是程序切換上,比如多進(jìn)程的服務(wù)器,負(fù)載伸縮性就非常差,有些空閑的客戶端也會(huì)Fork一個(gè)進(jìn)程服務(wù),這無(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)的吞吐率也要增加一倍。比如多線程程序中,由于要對(duì)競(jìng)爭(zhē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)程之間切換的開(kāi)銷(xiāo)太大,無(wú)法將盡可能多的CPU時(shí)間使用在網(wǎng)絡(luò)吞吐上,比如4CPU的服務(wù)器啟動(dòng)1000個(gè)繁忙的進(jìn)程基本上無(wú)法正常服務(wù)。系統(tǒng)伸縮性(System Scalability)非常好,增加CPU時(shí)一般系統(tǒng)吞吐率是線性增長(zhǎng)的。目前比較少見(jiàn)純粹的多進(jìn)程服務(wù)器了,特別是一個(gè)連接一個(gè)進(jìn)程這種。雖然性能很低,但是系統(tǒng)復(fù)雜度低(Simple),進(jìn)程很獨(dú)立,不需要處理鎖或者狀態(tài)。
- MT(Multi-Threaded)多線程模型:有的是每個(gè)連接一個(gè)線程,改進(jìn)型的是按照職責(zé)分連接,比如讀寫(xiě)分離的線程,幾個(gè)線程讀,幾個(gè)線程寫(xiě)。系統(tǒng)的魯棒性不好(Poor),一個(gè)連接或線程出現(xiàn)問(wèn)題,影響其他的線程,彼此互相影響。負(fù)載伸縮性(Load Scalability)比較好(Good),線程比進(jìn)程輕量一些,多個(gè)用戶線程對(duì)應(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ā)和鎖引入的問(wèn)題。
- EDSM(Event-Driven State Machine)事件驅(qū)動(dòng)的狀態(tài)機(jī)。比如select/poll/epoll,一般是單進(jìn)程單線程,這樣可以避免多進(jìn)程的鎖問(wèn)題,為了避免單程的系統(tǒng)伸縮問(wèn)題可以使用多進(jìn)程單線程,比如NGINX就是這種方式。系統(tǒng)魯棒性比較好(Good),一個(gè)進(jìn)程服務(wù)一部分的客戶端,有一定的隔離。負(fù)載伸縮性(Load Scalability)非常好(Great),沒(méi)有進(jìn)程或線程的切換,用戶空間的開(kāi)銷(xiāo)也非常少,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ī)的問(wèn)題,從堆開(kāi)辟協(xié)程的棧,將狀態(tài)保存在棧中,在異步IO等待(EAGAIN)時(shí),主動(dòng)切換(setjmp/longjmp)到其他的協(xié)程完成IO。也就是ST是綜合了EDSM和MT的優(yōu)勢(shì),不過(guò)ST的線程是用戶空間線程而不是系統(tǒng)線程,用戶空間線程也會(huì)有調(diào)度的開(kāi)銷(xiāo),不過(guò)比系統(tǒng)的開(kāi)銷(xiāo)要小很多。協(xié)程的調(diào)度開(kāi)銷(xiāo),和EDSM的大循環(huán)的開(kāi)銷(xiāo)差不多,需要循環(huán)每個(gè)激活的客戶端,逐個(gè)處理。而ST的主要問(wèn)題,在于平臺(tái)的適配,由于glibc的setjmp/longjmp是加密的無(wú)法修改SP棧指針,所以ST自己實(shí)現(xiàn)了這個(gè)邏輯,對(duì)于不同的平臺(tái)就需要自己適配,目前Linux支持比較好,Windows不支持,另外這個(gè)庫(kù)也不在維護(hù)有些坑只能繞過(guò)去,比較偏僻使用和維護(hù)者都很少,比如ST Patch修復(fù)了一些問(wèn)題。
我將Go也放在了ST這種模型中,雖然它是
多線程+協(xié)程,和SRS不同是多進(jìn)程+協(xié)程(SRS本身是單進(jìn)程+協(xié)程可以擴(kuò)展為多進(jìn)程+協(xié)程)。
從并發(fā)模型看Go的goroutine,Go有ST的優(yōu)勢(shì),沒(méi)有ST的劣勢(shì),這就是Go的并發(fā)模型厲害的地方了。當(dāng)然Go的多線程是有一定開(kāi)銷(xiāo)的,并沒(méi)有純粹多進(jìn)程單線程那么高的負(fù)載伸縮性,在活躍的連接過(guò)多時(shí),可能會(huì)激活多個(gè)物理線程,導(dǎo)致性能降低。也就是Go的性能會(huì)比ST或EDSM要差,而這些性能用來(lái)交換了系統(tǒng)的維護(hù)性,個(gè)人認(rèn)為很值得。除了goroutine,另外非常關(guān)鍵的就是chan。Go的并發(fā)實(shí)際上并非只有g(shù)oroutine,而是goroutine+chan,chan用來(lái)在多個(gè)goroutine之間同步。實(shí)際上在這兩個(gè)機(jī)制上,還有標(biāo)準(zhǔn)庫(kù)中的context,這三板斧是Go的并發(fā)的撒手锏。
- goroutine: Go對(duì)于協(xié)程的語(yǔ)言級(jí)別原生支持,一個(gè)go就可以啟動(dòng)一個(gè)協(xié)程。ST是通過(guò)函數(shù)來(lái)實(shí)現(xiàn)。
- chan和select: goroutine之間通信的機(jī)制,ST如果要實(shí)現(xiàn)兩個(gè)協(xié)程的消息傳遞和等待,只能自己實(shí)現(xiàn)queue和cond。如果要同步多個(gè)呢?比如一個(gè)協(xié)程要處理多種消息,包括用戶取消,超時(shí),其他線程的事件,Go提供了select關(guān)鍵字。參考
Share Memory By Communicating。 - context: 管理goroutine的組件,參考GOLANG使用Context管理關(guān)聯(lián)goroutine以及GOLANG使用Context實(shí)現(xiàn)傳值、超時(shí)和取消。參考
Go Concurrency Patterns: Timing out, moving on和Go Concurrency Patterns: Context。
由于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的控制方式:
- 錯(cuò)誤處理:比如底層函數(shù)發(fā)生錯(cuò)誤后,我們是忽略并告警(比如只是某個(gè)連接受到影響),還是選擇中斷整個(gè)服務(wù)(比如LICENSE到期)。
- 用戶取消:比如升級(jí)時(shí),我們需要主動(dòng)的遷移新的請(qǐng)求到新的服務(wù),或者取消一些長(zhǎng)時(shí)間運(yùn)行的goroutine,這就叫熱升級(jí)。
- 超時(shí)關(guān)閉:比如請(qǐng)求的最大請(qǐng)求時(shí)長(zhǎng)是30秒,那么超過(guò)這個(gè)時(shí)間,我們就應(yīng)該取消請(qǐng)求。一般客戶端的服務(wù)響應(yīng)是有時(shí)間限制的。
- 關(guān)聯(lián)取消:比如客戶端請(qǐng)求服務(wù)器,服務(wù)器還要請(qǐng)求后端很多服務(wù),如果中間客戶端關(guān)閉了連接,服務(wù)器應(yīng)該中止,而不是繼續(xù)請(qǐng)求完所有的后端服務(wù)。
而goroutine的管理,最開(kāi)始只有chan和sync,需要自己手動(dòng)實(shí)現(xiàn)goroutine的生命周期管理,參考Go Concurrency Patterns: Timing out, moving on和Go Concurrency Patterns: Context,這些都是goroutine的并發(fā)范式。
直接使用原始的組件管理goroutine太繁瑣了,后來(lái)在一些大型項(xiàng)目中出現(xiàn)了context這些庫(kù),并且Go1.7之后變成了標(biāo)準(zhǔn)庫(kù)的一部分。具體參考GOLANG使用Context管理關(guān)聯(lián)goroutine以及GOLANG使用Context實(shí)現(xiàn)傳值、超時(shí)和取消。
Context也有問(wèn)題:
- 支持Cancel、Timeout和Value,這些都是擴(kuò)張Context樹(shù)的節(jié)點(diǎn)。Cancel和Timeout在子樹(shù)取消時(shí)會(huì)刪除子樹(shù),不會(huì)一直膨脹;Value沒(méi)有提供刪除的函數(shù),如果他們有公共的根節(jié)點(diǎn),會(huì)導(dǎo)致這個(gè)Context樹(shù)越來(lái)越龐大;所以Value類型的Context應(yīng)該掛在Cancel的Context樹(shù)下面,這樣在取消時(shí)GC會(huì)回收。
- 會(huì)導(dǎo)致接口不一致或者奇怪,比如io.Reader其實(shí)第一個(gè)參數(shù)應(yīng)該是context,比如
Read(Context, []byte)函數(shù)?;蛘咛峁﹥商捉涌冢环N帶Contex,一種不帶Context。這個(gè)問(wèn)題還蠻困擾人的,一般在應(yīng)用程序中,推薦第一個(gè)參數(shù)是Context。 - 注意Context樹(shù),如果因?yàn)镃losure導(dǎo)致樹(shù)越來(lái)越深,會(huì)有調(diào)用棧的性能問(wèn)題。比如十萬(wàn)個(gè)長(zhǎng)鏈,會(huì)導(dǎo)致CPU占用500%左右。
備注:關(guān)于對(duì)Context的批評(píng),可以參考Context should go away for Go 2,作者覺(jué)得在標(biāo)準(zhǔn)庫(kù)中加context作為第一個(gè)參數(shù)不能理解,比如
Read(ctx context.Context等。
Links
由于簡(jiǎn)書(shū)限制了文章字?jǐn)?shù),只好分成不同章節(jié):
- Overview 為何Go有時(shí)候也叫Golang?為何要選擇Go作為服務(wù)器開(kāi)發(fā)的語(yǔ)言?是沖動(dòng)?還是騷動(dòng)?Go的重要里程碑和事件,當(dāng)年吹的那些牛逼,都實(shí)現(xiàn)了哪些?
- Could Not Recover 君可知,有什么panic是無(wú)法recover的?包括超過(guò)系統(tǒng)線程限制,以及map的競(jìng)爭(zhēng)寫(xiě)。當(dāng)然一般都能recover,比如Slice越界、nil指針、除零、寫(xiě)關(guān)閉的chan等。
- Errors 為什么Go2的草稿3個(gè)有2個(gè)是關(guān)于錯(cuò)誤處理的?好的錯(cuò)誤處理應(yīng)該怎么做?錯(cuò)誤和異常機(jī)制的差別是什么?錯(cuò)誤處理和日志如何配合?
- Logger 為什么標(biāo)準(zhǔn)庫(kù)的Logger是完全不夠用的?怎么做日志切割和輪轉(zhuǎn)?怎么在混成一坨的服務(wù)器日志中找到某個(gè)連接的日志?甚至連接中的流的日志?怎么做到簡(jiǎn)潔又夠用?
- 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)?小小的版本號(hào)為何會(huì)帶來(lái)大災(zāi)難?Go為什么推出了GOPATH、Vendor還要搞module和vgo?新建了16個(gè)倉(cāng)庫(kù)做測(cè)試,碰到了9個(gè)坑,搞清楚了gopath和vendor如何遷移,以及vgo with vendor如何使用(畢竟生產(chǎn)環(huán)境不能每次都去外網(wǎng)下載)。
- Concurrency & Control 服務(wù)器中的并發(fā)處理難在哪里?為什么說(shuō)Go并發(fā)處理優(yōu)勢(shì)占領(lǐng)了云計(jì)算開(kāi)發(fā)語(yǔ)言市場(chǎng)?什么是C10K、C10M問(wèn)題?如何管理goroutine的取消、超時(shí)和關(guān)聯(lián)取消?為何Go1.7專門(mén)將context放到了標(biāo)準(zhǔn)庫(kù)?context如何使用,以及問(wèn)題在哪里?
- Engineering Go在工程化上的優(yōu)勢(shì)是什么?為什么說(shuō)Go是一門(mén)面向工程的語(yǔ)言?覆蓋率要到多少比較合適?什么叫代碼可測(cè)性?為什么良好的庫(kù)必須先寫(xiě)Example?
- Go2 Transition Go2會(huì)像Python3不兼容Python2那樣作嗎?C和C++的語(yǔ)言演進(jìn)可以有什么不同的收獲?Go2怎么思考語(yǔ)言升級(jí)的問(wèn)題?
- SRS & Others Go在流媒體服務(wù)器中的使用。Go的GC靠譜嗎?Twitter說(shuō)相當(dāng)?shù)目孔V,有圖有真相。為何Go的聲明語(yǔ)法是那樣?C的又是怎樣?是拍的大腿,還是拍的腦袋?