如今十绑,微信擁有月活躍用戶8億。
不可否認(rèn)酷勺,當(dāng)今的微信后臺(tái)擁有著強(qiáng)大的并發(fā)能力本橙。
不過(guò), 正如羅馬并非一日建成鸥印;微信的技術(shù)也曾經(jīng)略顯稚嫩。
微信誕生于2011年1月坦报,當(dāng)年用戶規(guī)模為0.1億左右库说;2013年11月,微信月活躍用戶數(shù)達(dá)到3.55億片择,一躍成為亞洲地區(qū)擁有最大用戶群體的移動(dòng)終端即時(shí)通訊軟件潜的。
面對(duì)如此體量的提升,微信后臺(tái)也曾遭遇棘手的窘境谨敛;令人贊嘆的是技術(shù)人及時(shí)地做出了漂亮的應(yīng)對(duì)眶熬。
這背后有著怎樣的技術(shù)故事悼沈?
此時(shí)此刻,你在微信手機(jī)端發(fā)出的請(qǐng)求亡呵,是怎樣被后臺(tái)消化和處理的?
這次硫戈,InfoQ聚焦微信后臺(tái)解決方案之協(xié)程庫(kù)libco锰什。
該項(xiàng)目在保留后臺(tái)敏捷的同步風(fēng)格同時(shí),提高了系統(tǒng)的并發(fā)能力丁逝,節(jié)省了大量的服務(wù)器成本汁胆;自2013年起穩(wěn)定運(yùn)行于微信的數(shù)萬(wàn)臺(tái)機(jī)器之上。
本文源自InfoQ對(duì)Leiffy的采訪和《揭秘:微信如何用libco支撐8億用戶》的整理霜幼。
微信后端遇到了問(wèn)題
早期微信后臺(tái)因?yàn)闃I(yè)務(wù)需求復(fù)雜多變嫩码、產(chǎn)品要求快速迭代等需求,大部分模塊都采用了半同步半異步模型罪既。接入層為異步模型铸题,業(yè)務(wù)邏輯層則是同步的多進(jìn)程或多線程模型铡恕,業(yè)務(wù)邏輯的并發(fā)能力只有幾十到幾百。
隨著微信業(yè)務(wù)的增長(zhǎng)回挽,直到2013年中没咙,微信后臺(tái)機(jī)器規(guī)模已達(dá)到1萬(wàn)多臺(tái),涉及數(shù)百個(gè)后臺(tái)模塊千劈,RPC調(diào)用每分鐘數(shù)十億祭刚。在如此龐大復(fù)雜的系統(tǒng)規(guī)模下,每個(gè)模塊很容易受到后端服務(wù)或者網(wǎng)絡(luò)抖動(dòng)的影響墙牌。因此我們急需對(duì)微信后臺(tái)進(jìn)行異步化的改造涡驮。
異步化改造方案的考量
當(dāng)時(shí)我們有兩種選擇:
A 線程異步化:把所有服務(wù)改造成異步模型,等同于從框架到業(yè)務(wù)邏輯代碼的徹底改造
B 協(xié)程異步化:對(duì)業(yè)務(wù)邏輯非侵入的異步化改造喜滨,即只修該少量框架代碼
兩者相比捉捅,工作量和風(fēng)險(xiǎn)系數(shù)的差異顯而易見(jiàn)。雖然A方案服務(wù)器端多線程異步處理是常見(jiàn)做法虽风,對(duì)提高并發(fā)能力這個(gè)原始目標(biāo)非常奏效棒口;但是對(duì)于微信后臺(tái)如此復(fù)雜的系統(tǒng),這過(guò)于耗時(shí)耗力且風(fēng)險(xiǎn)巨大辜膝。
無(wú)論是異步模型還是同步模型无牵,都需要保存異步狀態(tài)。所以兩者在技術(shù)細(xì)節(jié)的相同點(diǎn)是厂抖,兩個(gè)方案茎毁,都是需要維護(hù)當(dāng)前請(qǐng)求的狀態(tài)。在A異步模型中方案忱辅,當(dāng)請(qǐng)求需要被異步執(zhí)行時(shí)七蜘,需要主動(dòng)把請(qǐng)求相關(guān)數(shù)據(jù)保存起來(lái),再等待狀態(tài)機(jī)的下一次調(diào)度執(zhí)行墙懂;而在B協(xié)程模型方案中橡卤,異步狀態(tài)的保存與恢復(fù)是自動(dòng)的,協(xié)程恢復(fù)執(zhí)行的時(shí)候就是上一次退出時(shí)的上下文损搬。
因此蒜魄,B協(xié)程方案不需要顯式地維護(hù)異步狀態(tài):一方面在編程上可以更簡(jiǎn)單和直接;另一方面協(xié)程中只需要保存少量的寄存器场躯。因此在復(fù)雜系統(tǒng)上谈为,協(xié)程服務(wù)的性能可能比純異步模型更優(yōu)。
綜合以上考慮踢关,最終我們選擇了B方案伞鲫,通過(guò)協(xié)程的方式對(duì)微信后臺(tái)上百個(gè)模塊進(jìn)行了異步化改造。
接管歷史遺留的同步風(fēng)格API
方案敲定之后签舞,接下來(lái)做的就是實(shí)現(xiàn)異步化的同時(shí)盡可能地少做代碼修改秕脓。
通常而言柒瓣,一個(gè)常規(guī)的網(wǎng)絡(luò)后臺(tái)服務(wù)需要connect、write吠架、read等系列步驟芙贫,如果使用同步風(fēng)格的API對(duì)網(wǎng)絡(luò)進(jìn)行調(diào)用,整個(gè)服務(wù)線程會(huì)因?yàn)榈却W(wǎng)絡(luò)交互而掛起傍药,這就會(huì)造成等待并占用資源磺平。原來(lái)的這種情況很明顯地影響到了系統(tǒng)的并發(fā)性能,但是當(dāng)初這樣的選擇是因?yàn)閷?duì)應(yīng)的同步編程風(fēng)格具有其獨(dú)特的優(yōu)勢(shì):代碼邏輯清晰拐辽、易于編寫(xiě)并且支持業(yè)務(wù)快速迭代敏捷開(kāi)發(fā)拣挪。
我們的改造方案需要消除同步風(fēng)格API的缺點(diǎn),但是同時(shí)還希望保持同步編程的優(yōu)點(diǎn)俱诸。
最后在不修改線上已有的業(yè)務(wù)邏輯代碼的情況下菠劝,我們的libco框架創(chuàng)新地接管了網(wǎng)絡(luò)調(diào)用接口(Hook)。把協(xié)程的讓出與恢復(fù)作為異步網(wǎng)絡(luò)IO中的一次事件注冊(cè)與回調(diào)睁搭。當(dāng)業(yè)務(wù)處理遇到同步網(wǎng)絡(luò)請(qǐng)求的時(shí)候赶诊,libco層會(huì)把本次網(wǎng)絡(luò)請(qǐng)求注冊(cè)為異步事件,當(dāng)前的協(xié)程讓出CPU占用园骆,CPU交給其它協(xié)程執(zhí)行舔痪。在網(wǎng)絡(luò)事件發(fā)生或者超時(shí)的時(shí)候,libco會(huì)自動(dòng)的恢復(fù)協(xié)程執(zhí)行遇伞。
libco的架構(gòu)
libco架構(gòu)從設(shè)計(jì)的時(shí)候就已經(jīng)確立下來(lái)了辙喂,最近的在GitHub上一次較大更新主要是功能上的更新捶牢。(注:libco為開(kāi)源項(xiàng)目鸠珠,源碼同步更新,可移步:https://github.com/tencent/libco)秋麸。
libco框架有三層:分別是協(xié)程接口層渐排、系統(tǒng)函數(shù)Hook層以及事件驅(qū)動(dòng)層。
協(xié)程接口層實(shí)現(xiàn)了協(xié)程的基本源語(yǔ)灸蟆。co_create驯耻、co_resume等簡(jiǎn)單接口負(fù)責(zé)協(xié)程創(chuàng)建于恢復(fù)。co_cond_signal類(lèi)接口可以在協(xié)程間創(chuàng)建一個(gè)協(xié)程信號(hào)量炒考,可用于協(xié)程間的同步通信可缚。
系統(tǒng)函數(shù)Hook層負(fù)責(zé)主要負(fù)責(zé)系統(tǒng)中同步API到異步執(zhí)行的轉(zhuǎn)換。對(duì)于常用的同步網(wǎng)絡(luò)接口斋枢,Hook層會(huì)把本次網(wǎng)絡(luò)請(qǐng)求注冊(cè)為異步事件帘靡,然后等待事件驅(qū)動(dòng)層的喚醒執(zhí)行。
事件驅(qū)動(dòng)層實(shí)現(xiàn)了一個(gè)簡(jiǎn)單高效的異步網(wǎng)路框架瓤帚,里面包含了異步網(wǎng)絡(luò)框架所需要的事件與超時(shí)回調(diào)描姚。對(duì)于來(lái)源于同步系統(tǒng)函數(shù)Hook層的請(qǐng)求涩赢,事件注冊(cè)與回調(diào)實(shí)質(zhì)上是協(xié)程的讓出與恢復(fù)執(zhí)行。
相比線程轩勘,選擇協(xié)程意味著筒扒?
比起線程,對(duì)于很多人而言绊寻,協(xié)程的應(yīng)用并不是那么輕車(chē)熟路花墩。
線程和協(xié)程的相同點(diǎn)是什么?
我們可以簡(jiǎn)單認(rèn)為協(xié)程是一種用戶態(tài)線程榛斯,它與線程一樣擁有獨(dú)立的寄存器上下文以及運(yùn)行棧观游,對(duì)程序員最直觀的效果就是,代碼可以在協(xié)程里面正常的運(yùn)作驮俗,就像在線程里面一樣懂缕。但是線程和協(xié)程還是有區(qū)別的,我們需要重點(diǎn)關(guān)注是運(yùn)行棧管理模式與協(xié)程調(diào)度策略王凑。關(guān)于這兩點(diǎn)的具體執(zhí)行搪柑,在本文后續(xù)部分會(huì)談及。
那兩者的不同點(diǎn)呢索烹?
協(xié)程的創(chuàng)建與調(diào)度相比線程要輕量得多工碾,而且協(xié)程間的通信與同步是可以無(wú)鎖的,任一時(shí)刻都可以保證只有本協(xié)程在操作線程內(nèi)的資源百姓。
我們的方案是使用協(xié)程渊额,但這意味著面臨以下挑戰(zhàn):
業(yè)界協(xié)程在C/C++環(huán)境下沒(méi)有大規(guī)模應(yīng)用的經(jīng)驗(yàn);
如何處理同步風(fēng)格的API調(diào)用,如Socket垒拢、mysqlclient等;
如何控制協(xié)程調(diào)度;
如何處理已有全局變量旬迹、線程私有變量的使用;
下面我們來(lái)探討如何攻克這四個(gè)挑戰(zhàn)。
挑戰(zhàn)之一:前所未有的大規(guī)模應(yīng)用C/C++協(xié)程
實(shí)際上求类,協(xié)程這個(gè)概念的確很早就提出來(lái)了奔垦,但是確是因?yàn)樽罱鼛啄暝谀承┱Z(yǔ)言中(如lua、go等)被廣泛的應(yīng)用而逐漸的被大家所熟知尸疆。但是真正用于C/C++語(yǔ)言的椿猎、并且是大規(guī)模生產(chǎn)的著實(shí)不多。
而這個(gè)libco框架中寿弱,除了協(xié)程切換時(shí)寄存器保存與恢復(fù)使用了匯編代碼犯眠,其它代碼實(shí)現(xiàn)都是用C/C++語(yǔ)言編寫(xiě)的。
那為什么我們選擇了C/C++語(yǔ)言症革?
當(dāng)前微信后臺(tái)絕大部分服務(wù)都基于C++筐咧,原因是微信最早的后臺(tái)開(kāi)發(fā)團(tuán)隊(duì)從郵箱延續(xù)而來(lái),郵箱團(tuán)隊(duì)一直使用C++作為后臺(tái)主流開(kāi)發(fā)語(yǔ)言地沮,而且C++能滿足微信后臺(tái)對(duì)性能和穩(wěn)定性的要求嗜浮。
我們的C++后臺(tái)服務(wù)框架增加了協(xié)程支持之后羡亩,高并發(fā)和快速開(kāi)發(fā)的矛盾解決了。開(kāi)發(fā)者絕大部分情況下只需要關(guān)注并發(fā)數(shù)的配置危融,不需要關(guān)注協(xié)程本身畏铆。其他語(yǔ)言我們也會(huì)在一些工具里面嘗試,但是對(duì)于整個(gè)微信后臺(tái)而言吉殃,C++仍是我們未來(lái)長(zhǎng)期的主流語(yǔ)言辞居。
挑戰(zhàn)之二:保留同步風(fēng)格的API
這里的做法我們?cè)谏衔闹刑岬搅颂幚硗斤L(fēng)格的API的思路方法:大部分同步風(fēng)格的API我們都通過(guò)Hook的方法來(lái)接管了,libco會(huì)在恰當(dāng)?shù)臅r(shí)機(jī)調(diào)度協(xié)程恢復(fù)執(zhí)行蛋勺。
怎樣防止協(xié)程庫(kù)調(diào)度器被阻塞瓦灶?
libco的系統(tǒng)函數(shù)Hook層主要處理同步API到異步執(zhí)行的轉(zhuǎn)換,我們當(dāng)前的hook層只處理了主要的同步網(wǎng)絡(luò)接口抱完,對(duì)于這些接口贼陶,同步調(diào)用會(huì)被異步執(zhí)行,不會(huì)導(dǎo)致系統(tǒng)的線程阻塞巧娱。當(dāng)然碉怔,我們還有少量未Hook的同步接口,這些接口的調(diào)用可能會(huì)導(dǎo)致協(xié)程調(diào)度器阻塞等待禁添。
與線程類(lèi)似撮胧,當(dāng)我們操作跨線程數(shù)據(jù)的時(shí)候,需要使用線程安全級(jí)別的函數(shù)老翘。而在協(xié)程環(huán)境下芹啥,也是有協(xié)程安全的代碼約束。在微信后臺(tái)铺峭,我們約束了不能使用導(dǎo)致協(xié)程阻塞的函數(shù)墓怀,比如pthread_mutex、sleep類(lèi)函數(shù)(可以用poll(NULL, 0, timeout) 代替)等逛薇。而對(duì)于已有系統(tǒng)的改造捺疼,就需要審核已有代碼是否符合協(xié)程安全規(guī)范疏虫。
挑戰(zhàn)之三:調(diào)度千萬(wàn)級(jí)協(xié)程
調(diào)度策略方面永罚,我們可以看下Linux的進(jìn)程調(diào)度,從早期的O(1)到目前CFS完全公平調(diào)度卧秘,經(jīng)過(guò)了很復(fù)雜的演進(jìn)過(guò)程呢袱,而協(xié)程調(diào)度事實(shí)上也是可以參考進(jìn)程調(diào)度方法的,比如說(shuō)你可以定義一種調(diào)度策略翅敌,使得協(xié)程在不同的線程間切換羞福,但是這樣做會(huì)帶來(lái)昂貴的切換代價(jià)。在進(jìn)程/線程上面蚯涮,后臺(tái)服務(wù)通常已經(jīng)做了足夠多的工作治专,使得多核資源得到充分使用卖陵,所以協(xié)程的定位應(yīng)該是在這個(gè)基礎(chǔ)上發(fā)揮最大的性能。
libco的協(xié)程調(diào)度策略很簡(jiǎn)潔张峰,單個(gè)協(xié)程限定在固定的線程內(nèi)部泪蔫,僅在網(wǎng)絡(luò)IO阻塞等待時(shí)候切出,在網(wǎng)絡(luò)IO事件觸發(fā)時(shí)候切回喘批,也就是說(shuō)在這個(gè)層面上面可以認(rèn)為協(xié)程就是有限狀態(tài)機(jī)撩荣,在事件驅(qū)動(dòng)的線程里面工作,相信后臺(tái)開(kāi)發(fā)的同學(xué)會(huì)一下子就明白了饶深。
那怎么實(shí)現(xiàn)千萬(wàn)級(jí)別呢餐曹?
libco默認(rèn)是每一個(gè)協(xié)程獨(dú)享一個(gè)運(yùn)行棧,在協(xié)程創(chuàng)建的時(shí)候敌厘,從堆內(nèi)存分配一個(gè)固定大小的內(nèi)存作為該協(xié)程的運(yùn)行棧台猴。如果我們用一個(gè)協(xié)程處理前端的一個(gè)接入連接,那對(duì)于一個(gè)海量接入服務(wù)來(lái)說(shuō)俱两,我們的服務(wù)的并發(fā)上限就很容易受限于內(nèi)存卿吐。
所以量級(jí)的問(wèn)題就轉(zhuǎn)換成了怎樣高效使用內(nèi)存的問(wèn)題。
為了解決這個(gè)問(wèn)題锋华,libco采用的是共享?xiàng)DJ轿斯佟#▊鹘y(tǒng)運(yùn)行棧管理有stackfull和stackless兩種模式)簡(jiǎn)單來(lái)講,是若干個(gè)協(xié)程共享同一個(gè)運(yùn)行棧毯焕。
同一個(gè)共享?xiàng)O碌膮f(xié)程間切換的時(shí)候衍腥,需要把當(dāng)前的運(yùn)行棧內(nèi)容拷貝到協(xié)程的私有內(nèi)存中。為了減少這種內(nèi)存拷貝次數(shù)纳猫,共享?xiàng)5膬?nèi)存拷貝只發(fā)生在不同協(xié)程間的切換婆咸。當(dāng)共享?xiàng)5恼加谜咭恢睕](méi)有改變的時(shí)候,則不需要拷貝運(yùn)行棧芜辕。
再具體一點(diǎn)講講共享?xiàng)5脑恚簂ibco默認(rèn)模式(stackfull) 滿足大部分的業(yè)務(wù)場(chǎng)景尚骄,每個(gè)協(xié)程獨(dú)占128k棧空間侵续,只需1G內(nèi)存就可以支持萬(wàn)級(jí)協(xié)程倔丈。 而共享?xiàng)J莑ibco新增的一個(gè)特性,可以支持單機(jī)千萬(wàn)協(xié)程状蜗,應(yīng)對(duì)海量連接特殊場(chǎng)景需五。實(shí)現(xiàn)原理上,共享?xiàng)DJ皆趥鹘y(tǒng)的stackfull和stackless兩種模式之間做了個(gè)微創(chuàng)新轧坎,用戶可以自定義分配若干個(gè)共享?xiàng)?nèi)存宏邮,協(xié)程創(chuàng)建時(shí)指定使用哪一個(gè)共享?xiàng)!?/p>
不同協(xié)程之間的切換、 如何主動(dòng)退出一個(gè)正在執(zhí)行的協(xié)程蜜氨?我們把共享同一塊棧內(nèi)存的多個(gè)協(xié)程稱為協(xié)程組械筛,協(xié)程組內(nèi)不同協(xié)程之間切換需要把棧內(nèi)存拷貝到協(xié)程的私有空間,而協(xié)程組內(nèi)同一個(gè)協(xié)程的讓出與恢復(fù)執(zhí)行則不需要拷貝棧內(nèi)存飒炎,可以認(rèn)為共享?xiàng)5臈?nèi)存是“寫(xiě)時(shí)拷貝”的变姨。
共享?xiàng)O碌膮f(xié)程切換與退出,與普通協(xié)程模式的API一致厌丑,co_yield與co_resume定欧,libco底層會(huì)實(shí)現(xiàn)共享?xiàng)5哪J较碌陌葱杩截悧?nèi)存。
挑戰(zhàn)之四:全局變量 VS私有變量
在stackfull模式下面怒竿,局部變量的地址是一直不變的砍鸠;而stackless模式下面,只要協(xié)程被切出耕驰,那么局部變量的地址就失效了爷辱,這是開(kāi)發(fā)者需要注意的地方。
libco默認(rèn)的棧模式是每一個(gè)協(xié)程獨(dú)享運(yùn)行棧的朦肘,在這個(gè)模式下饭弓,開(kāi)發(fā)者需要注意棧內(nèi)存的使用,盡量避免 char buf[128 * 1024] 這種超大棧變量的申請(qǐng)媒抠,當(dāng)棧使用大小超過(guò)本協(xié)程棧大小的時(shí)候弟断,就可能導(dǎo)致棧溢出的core。
而在共享?xiàng)DJ较屡可m然在協(xié)程創(chuàng)建的時(shí)候可以映射到一個(gè)比較大的棧內(nèi)存上面阀趴,但是當(dāng)本協(xié)程需要讓出給其它協(xié)程執(zhí)行的時(shí)候,已使用棧的拷貝保存開(kāi)銷(xiāo)也是有的苍匆,因此最好也是盡量減少大的局部變量使用刘急。更多的,共享?xiàng)DJ较陆龋驗(yàn)槭嵌鄠€(gè)協(xié)程共享了同一個(gè)検逯空間,因此检碗,用戶需要注意協(xié)程內(nèi)的局部棧變量地址不可以跨協(xié)程傳遞据块。
協(xié)程私有變量的使用場(chǎng)景與線程私有變量類(lèi)似,協(xié)程私有變量是全局可見(jiàn)的后裸,不同的協(xié)程會(huì)對(duì)同一個(gè)協(xié)程變量保存自己的副本瑰钮。開(kāi)發(fā)者可以通過(guò)我們的API宏聲明協(xié)程私有變量冒滩,在使用上無(wú)特別需要注意的地方微驶。
多進(jìn)程程序改造為多線程程序時(shí)候,我們可以用__thread來(lái)對(duì)全局變量進(jìn)行快速修改,而在協(xié)程環(huán)境下因苹,我們創(chuàng)造了協(xié)程變量ROUTINE_VAR苟耻,極大簡(jiǎn)化了協(xié)程的改造工作量。
關(guān)于協(xié)程私有變量扶檐,因?yàn)閰f(xié)程實(shí)質(zhì)上是線程內(nèi)串行執(zhí)行的凶杖,所以當(dāng)我們定義了一個(gè)線程私有變量的時(shí)候,可能會(huì)有重入的問(wèn)題款筑。比如我們定義了一個(gè)__thread的線程私有變量智蝠,原本是希望每一個(gè)執(zhí)行邏輯獨(dú)享這個(gè)變量的。但當(dāng)我們的執(zhí)行環(huán)境遷移到協(xié)程了之后奈梳,同一個(gè)線程私有變量杈湾,可能會(huì)有多個(gè)協(xié)程會(huì)操作它,這就導(dǎo)致了變量沖入的問(wèn)題攘须。為此漆撞,我們?cè)谧鰈ibco異步化改造的時(shí)候,把大部分的線程私有變量改成了協(xié)程級(jí)私有變量于宙。協(xié)程私有變量具有這樣的特性:當(dāng)代碼運(yùn)行在多線程非協(xié)程環(huán)境下時(shí)浮驳,該變量是線程私有的;當(dāng)代碼運(yùn)行在協(xié)程環(huán)境的時(shí)候捞魁,此變量是協(xié)程私有的至会。底層的協(xié)程私有變量會(huì)自動(dòng)完成運(yùn)行環(huán)境的判斷并正確返回所需的值。
協(xié)程私有變量對(duì)于現(xiàn)有環(huán)境同步到異步化改造起了舉足輕重的作用谱俭,同時(shí)我們定義了一個(gè)非常簡(jiǎn)單方便的方法定義協(xié)程私有變量奋献,簡(jiǎn)單到只需一行聲明代碼即可。
簡(jiǎn)而言之
一句話總結(jié)libco庫(kù)的原理旺上,在協(xié)程里面用同步風(fēng)格編寫(xiě)代碼瓶蚂,實(shí)際運(yùn)作是事件驅(qū)動(dòng)的有限狀態(tài)機(jī),由上層的進(jìn)程/線程負(fù)責(zé)多核資源的使用宣吱。
最終效果窃这,大功告成
我們?cè)岩粋€(gè)狀態(tài)機(jī)驅(qū)動(dòng)的純異步代理服務(wù)改成了基于libco協(xié)程的服務(wù),在性能上比之前提升了10%到20%征候,并且杭攻,在基于協(xié)程的同步模型下,我們很簡(jiǎn)單的就實(shí)現(xiàn)了批量請(qǐng)求的功能疤坝。
正如當(dāng)時(shí)所愿兆解,我們使用libco對(duì)微信后臺(tái)上百個(gè)模塊進(jìn)行了協(xié)程異步化改造,在整個(gè)的改造過(guò)程中跑揉,業(yè)務(wù)邏輯代碼基本沒(méi)有改變锅睛,修改只是在框架層代碼埠巨。我們所做的是把原先在線程內(nèi)執(zhí)行的業(yè)務(wù)邏輯轉(zhuǎn)到了協(xié)程上執(zhí)行。改造的工作主要是復(fù)核系統(tǒng)中線程私有變量现拒、全局變量辣垒、線程鎖的使用,確保在協(xié)程切換的時(shí)候不會(huì)數(shù)據(jù)錯(cuò)亂或者重入印蔬。
至今勋桶,微信后臺(tái)絕大部分服務(wù)都已是多進(jìn)程或多線程協(xié)程模型,并發(fā)能力相比之前有了質(zhì)的提升侥猬,而在這過(guò)程中應(yīng)運(yùn)而生的libco也成為了微信后臺(tái)框架的基石例驹。
作者簡(jiǎn)介
李方源, 微信高級(jí)工程師,目前負(fù)責(zé)微信后臺(tái)基礎(chǔ)框架及優(yōu)化退唠,致力于高性能眠饮、高可用的大規(guī)模分布式系統(tǒng)設(shè)計(jì)及研發(fā),先后參與微信后臺(tái)協(xié)程化改造項(xiàng)目铜邮、微信后臺(tái)框架重構(gòu)等項(xiàng)目仪召。
libco為開(kāi)源項(xiàng)目,源碼同步更新松蒜,可移步: https://github.com/tencent/libco