揭秘:微信如何用 libco 支撐8億用戶

2021-01-21 開源中國

libco是微信後臺大規模使用的c/c++協程庫,2013年至今穩定運行在微信後臺的數萬臺機器上。libco在2013年的時候作為騰訊六大開源項目首次開源,最近做了一次較大的更新。libco支持後臺敏捷的同步風格編程模式,同時提供系統的高並發能力。

libco支持的特性

支持CGI框架,輕鬆構建web服務(New);

支持gethostbyname、mysqlclient、ssl等常用第三庫(New);

可選的共享棧模式,單機輕鬆接入千萬連接(New);

完善簡潔的協程編程接口:

        ▪  類pthread接口設計,通過co_create、co_resume等簡單清晰接口即可完成協程的創建與恢復;

        ▪  類__thread的協程私有變量、協程間通信的協程信號量co_signal (New);

        ▪  非語言級別的lambda實現,結合協程原地編寫並執行後臺異步任務 (New);

        ▪  基於epoll/kqueue實現的小而輕的網絡框架,基於時間輪盤實現的高性能定時器。

libco產生的背景

早期微信後臺因為業務需求複雜多變、產品要求快速迭代等需求,大部分模塊都採用了半同步半異步模型。接入層為異步模型,業務邏輯層則是同步的多進程或多線程模型,業務邏輯的並發能力只有幾十到幾百。隨著微信業務的增長,系統規模變得越來越龐大,每個模塊很容易受到後端服務/網絡抖動的影響。

異步化改造的選擇

為了提升微信後臺的並發能力,一般的做法是把現網的所有服務改成異步模型。這種做法工程量巨大,從框架到業務邏輯代碼均需要做一次徹底的改造,耗時耗力而且風險巨大。於是開始考慮使用協程。

但使用協程會面臨以下挑戰:

    1.    業界協程在c/c++環境下沒有大規模應用的經驗;
    2.    如何控制協程調度;
    3.    如何處理同步風格的API調用,如Socket、mysqlclient等;
    4.    如何處理已有全局變量、線程私有變量的使用;

最終通過libco解決了上述的所有問題,實現了對業務邏輯非侵入的異步化改造。使用libco對微信後臺上百個模塊進行了協程異步化改造,改造過程中業務邏輯代碼基本無修改。至今,微信後臺絕大部分服務都已是多進程或多線程協程模型,並發能力相比之前有了質的提升,而libco也成為了微信後臺框架的基石。

libco框架

同步風格API的處理

對於同步風格的API,主要是同步的網絡調用,libco的首要任務是消除這些等待對資源的佔用,提高系統的並發性能。一個常規的網絡後臺服務,可能會經歷connect、write、read等步驟,完成一次完整的網絡交互。當同步的調用這些API的時候,整個線程會因為等待網絡交互而掛起。

雖然同步編程風格的並發性能並不好,但是它具有代碼邏輯清晰、易於編寫的優點,並可支持業務快速迭代敏捷開發。為了繼續保持同步編程的優點,並且不需修改線上已有的業務邏輯代碼,libco創新地接管了網絡調用接口(Hook),把協程的讓出與恢復作為異步網絡IO中的一次事件註冊與回調。當業務處理遇到同步網絡請求的時候,libco層會把本次網絡請求註冊為異步事件,本協程讓出CPU佔用,CPU交給其它協程執行。libco會在網絡事件發生或者超時的時候,自動的恢復協程執行。

大部分同步風格的API都通過Hook的方法來接管了,libco會在恰當的時機調度協程恢復執行。

千萬級協程支持

libco默認是每一個協程獨享一個運行棧,在協程創建的時候,從堆內存分配一個固定大小的內存作為該協程的運行棧。如果用一個協程處理前端的一個接入連接,那對於一個海量接入服務來說,服務的並發上限就很容易受限於內存。為此,libco也提供了stackless的協程共享棧模式,可以設置若干個協程共享同一個運行棧。同一個共享棧下的協程間切換的時候,需要把當前的運行棧內容拷貝到協程的私有內存中。為了減少這種內存拷貝次數,共享棧的內存拷貝只發生在不同協程間的切換。當共享棧的佔用者一直沒有改變的時候,則不需要拷貝運行棧。

libco協程的共享協程棧模式使得單機很容易接入千萬連接,只需創建足夠多的協程即可。通過libco共享棧模式創建1千萬的協程(E5-2670 v3 @ 2.30GHz * 2, 128G內存),每10萬個協程共享的使用128k內存,整個穩定echo服務的時候總內存消耗大概為66G。

協程私有變量

多進程程序改造為多線程程序時候,可以用__thread來對全局變量進行快速修改,而在協程環境下,創造了協程變量ROUTINE_VAR,極大簡化了協程的改造工作量。

因為協程實質上是線程內串行執行的,所以當定義了一個線程私有變量的時候,可能會有重入的問題。比如定義了一個__thread的線程私有變量,原本是希望每一個執行邏輯獨享這個變量的。但當執行環境遷移到協程了之後,同一個線程私有變量,可能會有多個協程會操作它,這就導致了變量衝入的問題。為此,在做libco異步化改造的時候,把大部分的線程私有變量改成了協程級私有變量。協程私有變量具有這樣的特性:當代碼運行在多線程非協程環境下時,該變量是線程私有的;當代碼運行在協程環境的時候,此變量是協程私有的。底層的協程私有變量會自動完成運行環境的判斷並正確返回所需的值。

協程私有變量對於現有環境同步到異步化改造起了舉足輕重的作用,同時定義了一個非常簡單方便的方法定義協程私有變量,簡單到只需一行聲明代碼即可。

gethostbyname的Hook方法

對於現網服務,有可能需要通過系統的gethostbyname API接口去查詢DNS獲取真實地址。在協程化改造的時候,發現hook的socket族函數對gethostbyname不適用,當一個協程調用了gethostbyname時會同步等待結果,這就導致了同線程內的其它協程被延時執行。

對glibc的gethostbyname源碼進行了研究,發現hook不生效主要是由於glibc內部是定義了__poll方法來等待事件,而不是通用的poll方法;同時glibc還定義了一個線程私有變量,不同協程的切換可能會重入導致數據不準確。最終gethostbyname協程異步化是通過Hook __poll方法以及定義協程私有變量解決的。

gethostbyname是glibc提供的同步查詢dns接口,業界還有很多優秀的gethostbyname的異步化解決方案,但是這些實現都需要引入一個第三方庫並且要求底層提供異步回調通知機制。libco通過hook方法,在不修改glibc源碼的前提下實現了的gethostbyname的異步化。

協程信號量

在多線程環境下,會有線程間同步的需求,比如一個線程的執行需要等待另一個線程的信號,對於這種需求,通常是使用pthread_signal 來解決的。在libco中,定義了協程信號量co_signal用於處理協程間的並發需求,一個協程可以通過co_cond_signal與co_cond_broadcast來決定通知一個等待的協程或者喚醒所有等待協程。

總結

libco是一個高效的c/c++協程庫,提供了完善的協程編程接口、常用的Socket族函數Hook等,使得業務可用同步編程模型快速迭代開發。隨著幾年來的穩定運行,libco作為微信後臺框架的基石發揮了舉足輕重的作用。

稿源: 騰訊開源

相關焦點

  • 「微信指數」上線 如何查詢你在8億用戶中的影響力?
    TechWeb3 月 24 日報導 文/辛磊中韓長沙一戰的當晚,微信悄然上線了「微信指數」功能。與百度指數、新浪微博微指數類似,這個基於微信 8 億多用戶而成的微信指數,能夠實時查詢微信熱點,甚至個人影響力指數。怎麼用?
  • Libco 協程基礎庫
    libco 是騰訊開源的一個有趣的協程基礎庫,僅有的幾個函數接口 co_create/co_resume/co_yield 再配合 co_poll, 可以支持同步或者異步的寫法,如線程庫一樣輕鬆,庫裡面提供了socket族函數的hook,包含如下內容:1.pthread風格的coroutine接口封裝2.事件循環以及超時機制3.基於glibc
  • 2020年抖音用戶有多少億 最新數據揭秘直播市場
    2020年抖音用戶有多少億?註冊用戶已經高達8億但是日活用戶目前是4億。
  • 走進支撐過8億用戶的Yahoo!數據中心
    是一家全球知名的網際網路公司,擁有過8億的活躍用戶,提供了60多個全球化產品,分別部署在20多個國家或地區的數十萬臺伺服器之上,然而雅虎全球的運維團隊卻僅有數百人。下面,我們通過雅虎北京全球研發中心高級系統運維工程師劉元概述的三個方面來了解雅虎的技術運維體系,剖析超大規模網絡應用的運維挑戰,走進Yahoo!數據中心!
  • 手機誤刪微信記錄如何恢復?揭秘快速恢復微信記錄的三個技巧!
    手機誤刪微信記錄如何恢復?揭秘快速恢復微信記錄的三個技巧! 2020年04月20日 14:00作者:黃頁編輯:黃頁 手機誤刪微信記錄如何恢復?
  • Facebook秒殺微信,全球用戶超過30億,微信依然停留在12億!
    根據微信統計數據,2月10日,微信官方發布2019年春節數據報告,從拜年、發紅包、走親戚、節假日等春節必備活動出發,對中國人的春節進行了解讀。從除夕到初五,微信消息發送量同比增長64.2%、8.23億人收發微信紅包、微信運動全體用戶走出9.63萬億步數..…10億日活的微信已經成為春節年俗的重要組成部分。
  • 微信小程序月活用戶超8億
    據《2020微信小程序半年報告》,截至2020年6月,微信小程序月活用戶規模已超8億,同比增長11.6%,月活躍用戶規模達億級以上的小程序增加至8個
  • 「直通」11億微信用戶的企業微信,能否裂變出OA新玩法
    年底了,微信大動作頻頻,繼朋友圈發表情包上熱搜後,企業微信3.0全新發布,也引發業內高度關注,號稱要「直通」11億微信用戶的企業微信要下一盤什麼棋?企業用戶該如何選擇?傳統OA廠商有何反應……企業微信3.0發布,誓言「直通」11億微信用戶圖什麼?
  • 騰訊揭秘 2 億同時在線:今天,你上 QQ 了嗎?
    4月11日,騰訊宣布QQ同時在線人數突破2億。今天騰訊在微博中發出詳細數據,揭秘這2億用戶是如何使用QQ的。從1999年騰訊成立開始,使用者一直在穩步增長。騰訊用了10年才讓人數增長了至了1億,但僅4年就讓使用人數翻了一倍。而且從趨勢上來看,增漲根本停不下來。
  • 用戶超12億的微信將迎來「兒童版」?你會讓孩子用嗎?
    微信這一則新動態,引起網友的熱議。微博已有超2.3億關注。有的網友直言要用,認為這多了種選擇,兒童版微信應該要簡潔些,廣告少些。也有的認為這很有必要,「兒童版如果不能登陸王者榮耀啥的,不能註冊相關遊戲帳戶,也不錯。」
  • 支付寶、微信之後,新支付巨頭崛起!用戶超3億,你用過嗎?
    據相關數據顯示,我國網際網路的使用人數已經達到了13.19億人,這一用戶數量佔到了全球網絡使用人數的32.17%。同時,我國的行動支付交易規模也達到了249.88萬億元。由此不難看出,我國無論是在網民數量還是在行動支付的普及程度上,都在全球遙遙領先。而說到行動支付,相信大家最為熟悉的應該就是我國的兩大行動支付「巨頭」——支付寶和微信。
  • 迅雷鏈總工程師:支撐億級用戶的區塊鏈技術革新
    面對區塊鏈行業最為關注的問題,區塊鏈技術如何才能脫虛向實、落地應用?來鑫表示,一方面,底層技術必須與企業業務的實際需求相結合,滿足他們的訴求。比如越是行業頭部企業,越是擔心自己的業務上鏈之後,後臺性能是否足夠支撐瞬時、大量的業務需求。解決這個問題,就需要足夠強勁的底層性能和擴展性作為支撐,企業才有使用區塊鏈技術進行業務轉型的信心。另一方面,需要不斷改善區塊鏈的開發環境,降低開發門檻和成本,有針對性地設計一些基礎設施、開發工具以減輕開發者的負擔。
  • 微信進入「收費時代」!2項功能不花錢不給用,12億用戶爭議不斷
    據統計顯示,截止2019年,微信的月活躍度用戶高達12億,要知道中國的總人口數量有14億人,也就是說,基本上在用智慧型手機的人,都在使用微信,甚至有人有好幾個微信號。微信可以說掌握著大部分用戶的「社交命運」,它的每一次升級、每一次政策都備受關注。從微信成立到現在已經過了9年時間,很多人存在疑問:微信是如何盈利的呢?
  • 阿里應用分發:揭秘後流量時代如何精準觸達用戶
    【TechWeb報導】6月8日消息,隨著智慧型手機業務增長的放緩,人口增長紅利逐漸消失,移動網際網路進入後流量時代。阿里應用分發以此為背景分析了後流量時代觸達用戶的新方法。
  • Facebook秒殺微信,全球用戶超30億,微信依然停留12億?
    現如今在中國人的手機中必有一款微信app,它成為中國人主要的網上社交工具。據統計,迄今為止,微信用戶的人數已有12億,而且這一數據如今還停留在12億上,如今用戶數量增長非常緩慢。與國外的Facebook相比,微信顯然是差距甚遠,Facebook的用戶已超過30億,而且還在不斷地增長。這不禁讓人疑惑,中國人都用的微信為何始終超越不了Facebook呢?首先,這兩款APP的運營商最初開發這兩款手機軟體的目的是不同,騰訊公司主營業務是以遊戲為主,開發微信的目的是為了吸引更多的用戶加入到遊戲當中來。
  • 為什麼香港用戶非常喜歡用WhatsApp,較少用微信?
    中國郵箱網訊 3月23日消息,微信的活躍度用戶數已經突破,可以說已經成為了中國最為流行的社交軟體。但香港用戶微信(WeChat)卻使用不多,這是為什麼呢?1用戶基數而香港人幾乎不用QQ,導致微信(WeChat)沒有了龐大的用戶基礎支撐。WhatsApp在許多國家都收到歡迎,用戶基數也不輸微信。
  • 10億用戶的微信表情指標體系是如何構建的?
    電視節目的評價我一直在想, 怎麼用指標來反應一個節目的受歡迎程度, 比如如何描述」嚮往的生活」 ,」青春有你」 這些綜藝節目是否火爆, 火爆的背後是否是健康的, 火爆的背後是否可以可持續的增長, 它的目標群體是否都觸達到了等等最直接的指標可能就是 觀看的觀眾數, 觀看的次數, 觀看的時長, 觀看的留存率, 完整觀看率, 切播率等然後從更深度來看, 應該是這個節目的觸達到了一些新的年齡層
  • 微信「龍頭地位」或將不保?又一社交軟體崛起,擁有用戶超8億
    馬化騰為廣東潮汕人,深圳大學首屆畢業生,畢業以後和幾個合伙人一起創立了騰訊公司,迅速推出了目前擁有11億用戶的社交軟體QQ,而馬化騰自己用的QQ號則是五位數00001號碼,這倒是無可厚非,畢竟他是騰訊公司的掌門人。馬化騰憑著社交軟體QQ,迅速讓騰訊發展壯大。
  • 全球下載破億 《Pokemon Go》用戶使用情況揭秘
    原標題:全球下載破億 《Pokemon Go》用戶使用情況揭秘   要說起最近一段時間最熱的話題,那就不得不提到任天堂、Niantic以及Pokemon公司聯合推出的《Pokemon Go》了。
  • 微信官方揭秘微信群控:以美女誘惑販賣色情視頻
    【TechWeb報導】昨天,微信安全中心發文《揭秘「微信群控」》。微信群控通過群控技術,批量模擬正常人行為來謀利,微信上很多惡意行為都是通過它來完成的。微信官方揭秘微信群控:以美女誘惑販賣色情視頻微信群控設備被一些不法分子利用用於非法牟利。不僅篡改GPS使用虛擬定位,還可以將微信的所有操作批量化自動化執行,最常見的就是色情牟利。