測試表明,Async Python 遠(yuǎn)不如同步方式)
多數(shù)人曉得async具備更高的并發(fā)性, 這表明針對像動(dòng)態(tài)網(wǎng)站或者Web API這類常見任務(wù), async性能更佳。然而令人可惜的是, async 于解釋器而言, 并非是一條加速條。在當(dāng)下符合實(shí)際情況的數(shù)據(jù)可查看下圖之中, 異步網(wǎng)絡(luò)框架的吞吐量也就是每秒鐘的請求量表現(xiàn)更為差勁, 而且響應(yīng)延遲也要大出許多。基準(zhǔn)結(jié)果我測試了各種不同的同步和異步的 Web 服務(wù)器配置。50分位數(shù)的響應(yīng)時(shí)間單位為毫秒, 99分位數(shù)的響應(yīng)時(shí)間單位也是毫秒, 吞吐量單位是每秒的請求量, 這種情況下該表依照P99進(jìn)行排序, 我覺得這極有可能是現(xiàn)實(shí)世界里至為重要的統(tǒng)計(jì)指標(biāo)。一些注意事項(xiàng)表現(xiàn)最好的是同步框架但 Flask 的吞吐量比其他的要低表現(xiàn)差的全都是異步框架異步框架的響應(yīng)延遲也差很多基于 的循環(huán)比內(nèi)置的 循環(huán)做得更好。如果不得不使用 請選擇 。這些基準(zhǔn)測試有代表性嗎我持有這樣的看法, 我盡可能地使得基準(zhǔn)運(yùn)行的那種場景去貼近實(shí)際的狀況, 下面呈現(xiàn)的是所運(yùn)用的架構(gòu)。我竭盡所能地去模擬那貼近現(xiàn)實(shí)狀況般的部署情形擁有一個(gè)反向代理, 中間所放置的是代碼, 而在其后方則是一個(gè)數(shù)據(jù)庫。我同樣運(yùn)用了數(shù)據(jù)庫連接池, 這乃是在真實(shí)的網(wǎng)絡(luò)應(yīng)用部署過程當(dāng)中較為常見的一種做法起碼就對于而言是這種狀況。經(jīng)由隨機(jī)關(guān)鍵碼查詢數(shù)據(jù)庫特定行的測試應(yīng)用程序, 將以JSON格式予以返回, 完整源代碼可參看:為什么工作進(jìn)程 數(shù)設(shè)置不一樣用來決定最佳數(shù)量究竟是多少的規(guī)則是相當(dāng)簡單的, 對于每一個(gè)框架而言, 我起始于1個(gè), 繼而連續(xù)不斷地增加數(shù)量, 一直達(dá)到性能變得差些的時(shí)候的那個(gè)數(shù)量, 此中規(guī)則即為如此。Async 框架與 sync 框架最佳數(shù)量存在差異, 緣由很簡單, async 框架因具備 IO 并發(fā)性, 致使一個(gè)進(jìn)程可令一個(gè) CPU 達(dá)到滿載。然而同步卻別有不同, 它們于進(jìn)行IO操作之際會(huì)開啟阻塞調(diào)用, 一直到IO操作完結(jié)。所以說, 它們所需具備的更多一些, 目的在于保證其在負(fù)載狀況下所有CPU核心始終維持滿負(fù)荷行動(dòng)狀態(tài)。關(guān)于這方面的更多信息請參見 文檔。通常來講, 我們提議將(2乘以$)加上1當(dāng)作起始的數(shù)量。雖說此公式并非十分科學(xué), 不過它是基于這般假設(shè): 針對一個(gè)給定的core, 當(dāng)有一個(gè)在處理請求之際, 另外一個(gè)能夠從套接字里進(jìn)行讀寫數(shù)據(jù)。機(jī)器規(guī)格我于一種為CX31的機(jī)器類型之上, 開展了基準(zhǔn)測試, 該機(jī)器是配有4 vCPU以及8 GB內(nèi)存的, 其運(yùn)行于20.04之上。于另外一臺(tái)規(guī)模較小的虛擬機(jī)之上, 運(yùn)行了施壓程序。為什么 async 表現(xiàn)更差吞吐量將請求量除以秒所得的吞吐量, 其最為關(guān)鍵的要素并非是async或者是sync, 而是究竟有多少代碼被替換給了本地代碼。簡而言之, 你能夠替換的對性能具有敏感性的代碼數(shù)量越多, 那么性能也就會(huì)越好。這屬于性能戰(zhàn)術(shù), 擁有著悠久的歷史另可查看: numpy。與UWSGI其每個(gè)大約有著5.3k請求量每秒涵蓋了數(shù)量眾多的C代碼, 標(biāo)準(zhǔn)約3.4k請求量每秒是基于純粹的。相對于那個(gè)默認(rèn)服務(wù)器每秒約4.5k的請求量而言, 每秒約4.9k請求的這個(gè)盡管它也安裝了其可選的“加速”竟然替換了更多的代碼。延時(shí)在響應(yīng)延遲方面, 問題呈現(xiàn)出更為復(fù)雜的狀況。在請求負(fù)載情形下, async的表現(xiàn)相當(dāng)糟糕, 延遲開始急劇飆升, 相較于傳統(tǒng)的同步部署, 延遲的程度要大出許多。為何會(huì)是這般狀況? 于async情形下, 多線程呈現(xiàn)為合作式, 確切來講, 就是線程不會(huì)被諸如內(nèi)核這般的中央治理者予以打斷, 反而是要主動(dòng)地將執(zhí)行時(shí)間讓予他人。處在該情境里, 執(zhí)行時(shí)間是在三個(gè)語言關(guān)鍵詞之上進(jìn)行讓渡的, 這三個(gè)關(guān)鍵詞分別是: await、async for以及async with。這表明執(zhí)行的時(shí)間并非是那種 “公平” 的分配形式, 存在這樣一種情況, 那就是一個(gè)線程在進(jìn)行工作期間, 有可能會(huì)在不經(jīng)意間致使另一個(gè)線程的 CPU 時(shí)間被剝奪, 進(jìn)而處于饑餓狀態(tài)。而延遲比較不穩(wěn)定, 其原因正是如此。相比起來, 傳用傳統(tǒng)的同步方式 , 像是UWSGI , 采用的乃是內(nèi)核調(diào)度器的那種搶占式Pre-的多進(jìn)程 , 其工作所持原理是借由周期性地給進(jìn)程從執(zhí)行里就進(jìn)行交換出去 , 以此來確保公平性所在。這所意味的是時(shí)間的分配會(huì)更為公平 , 延遲方面的差異會(huì)更低。為什么其他基準(zhǔn)顯示的結(jié)果不同大多數(shù)別的基準(zhǔn), 特別那些源自async框架作者的基準(zhǔn), 壓根就沒給同步框架配置充足的, 這表明, 這些同步框架事實(shí)上沒辦法合理運(yùn)用實(shí)際可用的大半CPU時(shí)間。這里呈現(xiàn)的, 是項(xiàng)目的一個(gè)樣本基準(zhǔn), 我未曾對這個(gè)框架進(jìn)行測試, 原因在于它屬于一個(gè)不太流行的框架。宣稱在吞吐量方面比Flask高出五百個(gè)百分點(diǎn), 然而, 當(dāng)我去審查他們的基準(zhǔn)代碼之時(shí), 發(fā)現(xiàn)他們不正確地把Flask配置成每個(gè)CPU使用一個(gè) , 當(dāng)我把這個(gè)問題糾正過來的時(shí)候, 得到了以下這些結(jié)果。運(yùn)用比Flask更具吞吐量優(yōu)勢的實(shí)則僅為18%, 而Flask是我測試當(dāng)中擁有較低吞吐量的同步框架之一, 故而我覺得一個(gè)更為優(yōu)異的同步設(shè)置會(huì)比其要快出許多, 盡管此圖看上去頗為令人印象深刻。另外還有一個(gè)問題, 那就是好多基準(zhǔn)都會(huì)把響應(yīng)延遲的統(tǒng)計(jì)數(shù)據(jù)給去除掉, 然后側(cè)重于吞吐量的結(jié)果比如說有的基準(zhǔn)根本就沒提及它。可是呢, 增加吞吐量實(shí)際上能夠借助簡單地增添機(jī)器來達(dá)成提高, 不過要是在高負(fù)載狀況下延遲表現(xiàn)不好的話, 卻并沒有直接可以解決的辦法。只有在延遲在可接受的范圍內(nèi)提高吞吐量才真正有意義。進(jìn)一步的推理、假設(shè)和傳聞盡管基準(zhǔn)測試于設(shè)計(jì)層面竭力靠攏現(xiàn)實(shí), 然而它依舊遠(yuǎn)比現(xiàn)實(shí)生活里的工作負(fù)載單調(diào)許多, 所有請求皆會(huì)開展一次數(shù)據(jù)庫查詢, 接著會(huì)將此查詢用于做相同之事。真實(shí)的應(yīng)用往往具備更豐富多樣的變化, 存在一些耗時(shí)較長以及耗時(shí)較短的操作, 一些請求進(jìn)行了諸多IO操作, 另外一些則耗費(fèi)了大量CPU資源。似乎有理由去假設(shè), 依據(jù)我的經(jīng)驗(yàn)亦是這般, 在真實(shí)的應(yīng)用當(dāng)中, 延遲變化實(shí)際上會(huì)大幅更高。在這般情形之下, 我的那種預(yù)示著async應(yīng)用性能會(huì)更具問題的預(yù)感出現(xiàn)了。公開流傳的那些傳聞和這個(gè)想法是相契合的。Dan分享了他的經(jīng)歷, 他的經(jīng)歷是在Etsy管理一個(gè)基于系統(tǒng)的經(jīng)歷, 似乎那個(gè)基于該系統(tǒng)的系統(tǒng)受到了延遲變大的困擾。的顧問提及, 盡管, 于整體吞吐量方面表現(xiàn)良好, 然而冷僻的訪問請求, 有可能會(huì)呈現(xiàn)出嚴(yán)重的延遲狀況, 此情形對于。Etsy的系統(tǒng)對于 PHP 前端而言, 這算得上是個(gè)問題, 畢竟其具體的使用方式呈現(xiàn)出一種狀況, 即為每一個(gè) web 請求, 都將會(huì)展開幾百次或者幾千次的訪問行為。此書的作者名為Mike Bayer , 在幾年之前創(chuàng)作了《異步 以及數(shù)據(jù)庫》(1) , 其所著之書中從稍稍不同一點(diǎn)的一個(gè)角度對異步這一問題予以思考 , 并且他還開展了基準(zhǔn)測試 , 經(jīng)測試發(fā)現(xiàn)其效率比較低。by the Bay撰寫了一篇名為《我們必須談?wù)?、、 這件事》的文章(1), 在該文章里描繪了因 配置致使的操作混亂, 我于生產(chǎn)過程中也碰到過 的麻煩盡管和性能沒有關(guān)聯(lián)。尚有一事需提及, 于設(shè)定這些基準(zhǔn)之際, 每一項(xiàng)async實(shí)現(xiàn), 最終皆以一種令人厭煩之樣式出現(xiàn)故障。父進(jìn)程在沒終止任何子進(jìn)程時(shí)就退出了, 這致使我得去尋覓那些仍在8001端口活躍著的子進(jìn)程。曾有一回, 拋出了一個(gè)和文件描述符相關(guān)聯(lián)的相當(dāng)嚴(yán)重的內(nèi)部錯(cuò)誤, 可它并沒退出所以任何進(jìn)程監(jiān)控腳本都不會(huì)重啟它——這罪過可不小。同樣在本地碰到了問題, 不過我忘掉了具體是怎樣碰到的。所有這些錯(cuò)誤均是短暫 的, 運(yùn)用 不難解決。鑒于實(shí)際情況 , 我不愿在生產(chǎn)環(huán)境里負(fù)責(zé)針對這些庫 的代碼安排職責(zé)。與之相較 , 我于使用 或UWSGI期間 , 未曾遭遇任何問題 , 只是UWSGI在應(yīng)用未正確加載之際 , 是不會(huì)退出 的。總結(jié)我的提議是, 鑒于性能方面的考量, 采用平常的、同步的就行, 不過要盡可能運(yùn)用代碼。對于而言, 要是吞吐量絕對關(guān)鍵, 值得思索Flask以外的框架, 然而即便在UWSGI情形下的Flask, 也具備最優(yōu)的延遲特性。感謝 Tudor 幫忙檢查了文章中的數(shù)據(jù)。參閱寫過幾篇文章的Flask作者, 表達(dá)了他對async的擔(dān)憂第一篇是《我不理解的》(1), 它對async技術(shù)做了非常好的解釋最近又發(fā)了《我感覺不到async的壓力》(2), 里面提到。async/await很不錯(cuò), 然而它促使眾人去編寫一些在負(fù)載增大之后會(huì)出現(xiàn)災(zāi)難性后果的事物。《你的函數(shù)是什么顏色》這篇文章, 解釋了一些原因, 這些原因是, 一個(gè)語言若同時(shí)設(shè)有同步以及異步, 開發(fā)起來就會(huì)相對比較痛苦。函數(shù)著色屬于 里的一個(gè)大問題, 當(dāng)下社區(qū)令人悲哀地劃分成寫同步代碼的人以及寫async代碼的人, 他們沒辦法共享同一個(gè)庫。更糟糕的所在是, 部分異步庫跟另外一些異步庫不兼容, 因而異步 社區(qū)愈發(fā)分裂。克里斯, 近來撰寫了一篇文稿, 當(dāng)中也涉及到了延遲方面的問題, 以及標(biāo)準(zhǔn)庫里的某些注腳。令人遺憾的是, 這是一種會(huì)致使異步程序愈發(fā)難以妥善處理的問題。他有的想法是, 庫這個(gè)概念是不正確的。令我擔(dān)憂的情形是, 要是探討PEPs規(guī)范之中的那些先輩們不清楚呢, 像處于我這般狀況的尋常開發(fā)者就更沒有希望了。英文原文這篇文章是經(jīng)過高可用架構(gòu)進(jìn)行翻譯的, 是關(guān)于技術(shù)原創(chuàng)以及架構(gòu)實(shí)踐方面的文章, 要是你有稿件的話, 可以經(jīng)由公眾號(hào)菜單里的「聯(lián)系我們」進(jìn)行投稿。高可用架構(gòu)改變互聯(lián)網(wǎng)的構(gòu)建方式大多數(shù)人都知道 async 具有更高的并發(fā)性。這意味著對于常見的任務(wù)如動(dòng)態(tài)網(wǎng)站或 Web API, async 性能更好。但遺憾的是async 對于 解釋器來說并不是一個(gè)加速條。在現(xiàn)實(shí)條件下的數(shù)據(jù)見下圖異步網(wǎng)絡(luò)框架的吞吐量請求量/秒更差響應(yīng)延遲也大得多。基準(zhǔn)結(jié)果我測試了各種不同的同步和異步的 Web 服務(wù)器配置。第 50 和 99 分位數(shù)的響應(yīng)時(shí)間單位是毫秒 吞吐量單位是每秒請求量。該表按 P99 排序我認(rèn)為這可能是現(xiàn)實(shí)世界中最重要的統(tǒng)計(jì)指標(biāo)。一些注意事項(xiàng)表現(xiàn)最好的是同步框架但 Flask 的吞吐量比其他的要低表現(xiàn)差的全都是異步框架異步框架的響應(yīng)延遲也差很多基于 的循環(huán)比內(nèi)置的 循環(huán)做得更好。如果不得不使用 請選擇 。這些基準(zhǔn)測試有代表性嗎我認(rèn)為如此我盡量讓基準(zhǔn)運(yùn)行的場景貼近真實(shí)下面是使用的架構(gòu)。我盡可能地模擬真實(shí)世界的部署一個(gè)反向代理中間是 代碼后面一個(gè)數(shù)據(jù)庫。我還使用了數(shù)據(jù)庫連接池這是真實(shí)的 Web 應(yīng)用部署中常見的做法至少對于 來說是這樣。測試的應(yīng)用程序通過隨機(jī) key 查詢數(shù)據(jù)庫某一行并以 JSON 形式返回。完整的源代碼可以參看 為什么工作進(jìn)程 數(shù)設(shè)置不一樣決定最佳 數(shù)量是多少的規(guī)則很簡單對于每個(gè)框架我從 1 個(gè) 開始連續(xù)增加數(shù)量直到性能變差。Async 和 sync 框架的最佳 數(shù)量在有所不同原因很簡單async 框架由于其 IO 并發(fā)性一個(gè) 進(jìn)程就能讓一個(gè) CPU 跑滿。而同步 就不一樣了它們做 IO 時(shí)會(huì)調(diào)用阻塞直到 IO 完成。因此它們需要有更多的 以確保在負(fù)載時(shí)所有 CPU 核心始終處于滿負(fù)荷狀態(tài)。關(guān)于這方面的更多信息請參見 文檔。一般來說我們建議 (2 x $) 1 作為開始的 數(shù)量。雖然這個(gè)公式并不太科學(xué)但它是基于這樣的假設(shè)對于一個(gè)給定的 core當(dāng)一個(gè) 在處理請求時(shí)另外一個(gè) 可以從套接字中讀寫數(shù)據(jù)。機(jī)器規(guī)格我在 的 CX31 機(jī)器類型上運(yùn)行了基準(zhǔn)測試它是一個(gè)4 vCPU / 8 GB 內(nèi)存的機(jī)器運(yùn)行在 20.04 上。在另一個(gè)較小的虛擬機(jī)上運(yùn)行了施壓程序。為什么 async 表現(xiàn)更差吞吐量吞吐量(即請求量/秒)最主要的因素不是 async 還是 sync而是有多少 代碼被替換成了本地代碼。簡單的說你能替換的對性能敏感的 代碼越多性能就越好。這是 性能戰(zhàn)術(shù)歷史悠久另見numpy。和 UWSGI每個(gè)約 5.3k請求量/秒包含了大量的 C 代碼。標(biāo)準(zhǔn) 約 3.4k請求量/秒基于純 。 (~4.9k請求/秒)比 的默認(rèn)服務(wù)器(~4.5k請求量/秒)替換了更多的 代碼(盡管 也安裝了它的可選 加速)。延時(shí)在響應(yīng)延遲上問題更復(fù)雜。在請求負(fù)載下async 的表現(xiàn)很糟糕延遲開始飆升比傳統(tǒng)的同步部署延遲的程度要大得多。為什么會(huì)這樣呢在 async 中多線程是合作式co-的簡單來說就是線程不被中央治理者比如內(nèi)核打斷而是要主動(dòng)把執(zhí)行時(shí)間讓給別人。在 中執(zhí)行時(shí)間是在三個(gè)語言關(guān)鍵詞上讓渡的await、async for 和 async with。這意味著執(zhí)行時(shí)間并不是 公平 分配的一個(gè)線程在工作時(shí)可能會(huì)無意中餓死另一個(gè)線程的 CPU 時(shí)間。這就是為什么延遲比較不穩(wěn)定的原因。相比之下傳統(tǒng)的同步 比如 UWSGI使用的是內(nèi)核調(diào)度器的搶占式Pre-的多進(jìn)程它的工作原理是通過周期性地將進(jìn)程從執(zhí)行中交換出來以保證公平性。這意味著時(shí)間的分配更加公平延遲差異更低。為什么其他基準(zhǔn)顯示的結(jié)果不同大多數(shù)其他基準(zhǔn)尤其是那些來自 async 框架作者的基準(zhǔn)根本沒有為同步框架配置足夠的 。這意味著這些同步框架實(shí)際上無法合理使用真正可用的大部分 CPU 時(shí)間。下面是 項(xiàng)目的一個(gè)樣本基準(zhǔn)我沒有測試這個(gè)框架因?yàn)樗且粋€(gè)不太流行的框架。聲稱比 Flask 高出 500% 的吞吐量。然而當(dāng)我審查他們的基準(zhǔn)代碼時(shí)發(fā)現(xiàn)他們錯(cuò)誤地將 Flask 配置為每個(gè) CPU 使用一個(gè) 。當(dāng)我糾正這個(gè)問題時(shí)得到了以下結(jié)果。使用 比 Flask 的吞吐量優(yōu)勢其實(shí)只有 18%。Flask 是我測試過的吞吐量較低的同步框架之一所以我認(rèn)為一個(gè)更好的同步設(shè)置會(huì)比 快得多盡管這個(gè)圖看起來令人印象深刻。另一個(gè)問題是許多基準(zhǔn)都會(huì)去掉響應(yīng)延遲的統(tǒng)計(jì)數(shù)據(jù)而傾向于吞吐量結(jié)果例如 的基準(zhǔn)甚至沒有提到它。然而增加吞吐量其實(shí)可以通過簡單增加機(jī)器來提高但在高負(fù)載下的延遲不佳的話并沒有直接的解決辦法。只有在延遲在可接受的范圍內(nèi)提高吞吐量才真正有意義。進(jìn)一步的推理、假設(shè)和傳聞雖然基準(zhǔn)測試在設(shè)計(jì)方面盡量接近現(xiàn)實(shí)但它仍然比現(xiàn)實(shí)生活中的工作負(fù)載要單調(diào)得多 —— 所有的請求都會(huì)做一個(gè)數(shù)據(jù)庫查詢都會(huì)用這個(gè)查詢做同樣的事情。真實(shí)的應(yīng)用通常會(huì)有更豐富的變化會(huì)有一些慢的以及快的操作一些請求做了很多 IO另外一些使用了很多 CPU。似乎有理由假設(shè)根據(jù)我的經(jīng)驗(yàn)也是如此在真實(shí)的應(yīng)用中延遲變化實(shí)際上要高得多。在這種情況下我的預(yù)感 async 應(yīng)用的性能會(huì)更有問題。公開的傳聞與這個(gè)想法一致。Dan 分享了他在 Etsy 管理一個(gè)基于 系統(tǒng)的經(jīng)歷。似乎那個(gè)系統(tǒng)受到了延遲變大的困擾。的顧問說雖然 在整體吞吐量上很好但冷僻的訪問請求可能會(huì)出現(xiàn)嚴(yán)重的延遲這對Etsy的系統(tǒng)來說是個(gè)問題因?yàn)?PHP 前端的使用方式是每個(gè) web 請求都會(huì)訪問幾百或幾千次。的作者 Mike Bayer 在幾年前寫了《異步 和數(shù)據(jù)庫》(1)他在書中從一個(gè)稍微不同的角度考慮了異步的問題。他還進(jìn)行了基準(zhǔn)測試發(fā)現(xiàn) 的效率較低。by the Bay 寫了一篇文章《我們必須談?wù)?、、 這件事》(1)文章中描述了基于 配置所產(chǎn)生的操作混亂。我也曾在生產(chǎn)中遇到過 的麻煩雖然與性能無關(guān)。我還需要提到的一件事是在設(shè)置這些基準(zhǔn)的過程中每一個(gè) async 實(shí)現(xiàn)都最終以一種令人討厭的方式掛掉。的父進(jìn)程在沒有終止任何子進(jìn)程的情況下就退出了這意味著我不得不去尋找那些還在 8001 端口的子進(jìn)程。有一次 拋出了一個(gè)與文件描述符有關(guān)的內(nèi)部嚴(yán)重錯(cuò)誤但它并沒有退出 (因此任何進(jìn)程監(jiān)控腳本都不會(huì)重新啟動(dòng)它 —— 這可是大罪)。 也在本地遇到了麻煩但我忘了具體是怎么遇到的。所有這些錯(cuò)誤都是短暫的用 很容易解決。但實(shí)際我不想在生產(chǎn)環(huán)境中負(fù)責(zé)基于這些庫的代碼。相比之下我在使用 或 UWSGI 時(shí)沒有遇到任何問題 —— 除了UWSGI 在應(yīng)用沒有正確加載時(shí)不會(huì)退出。總結(jié)我的建議是出于性能的考慮使用普通的、同步的 即可但盡量使用 代碼。對于 來說如果吞吐量是最重要的值得考慮 Flask 以外的框架但即使是 UWSGI 下的 Flask, 也有最好的延遲特性。感謝 Tudor 幫忙檢查了文章中的數(shù)據(jù)。參閱Flask 作者已經(jīng)寫過幾篇文章表達(dá)了他對 async 的擔(dān)憂第一篇是《我不理解 的 》(1)對 async 技術(shù)做了非常好的解釋最近又發(fā)了《我感覺不到 async 的壓力》(2)里面提到async/await 非常好但它鼓勵(lì)大家寫一些負(fù)載變大后出現(xiàn)災(zāi)難性結(jié)果的東西。《你的函數(shù)是什么顏色》這篇文章解釋了一個(gè)語言如果同時(shí)存在同步和異步開發(fā)起來比較痛苦的一些原因。函數(shù)著色是 中的一個(gè)大問題現(xiàn)在社區(qū)很悲哀地分成了寫同步代碼的人和寫 async 代碼的人 —— 他們不能共享同一個(gè)庫。更糟糕的是一些異步庫還與另外一些異步庫不兼容所以異步 社區(qū)更加分裂。Chris 最近寫了一篇文章其中也提到了延遲問題和 標(biāo)準(zhǔn)庫中的一些注腳。不幸的是這是一種讓異步程序更難搞好的問題。