中文字幕在线观看,亚洲а∨天堂久久精品9966,亚洲成a人片在线观看你懂的,亚洲av成人片无码网站,亚洲国产精品无码久久久五月天

RxJava 在閑魚系統(tǒng)吞吐量提升上的實踐

2018-08-16    來源:編程學(xué)習(xí)網(wǎng)

容器云強(qiáng)勢上線!快速搭建集群,上萬Linux鏡像隨意使用

引言

響應(yīng)式編程最簡單的定義是Reactive programming is programming with asynchronous data streams。無論是從Spring5中引入的響應(yīng)式編程框架還是java9中集成的響應(yīng)式流,都能看到響應(yīng)式編程的影子?梢哉f響應(yīng)式編程代表了未來編程的方向。

響應(yīng)式編程其天然就是非阻塞的,當(dāng)數(shù)據(jù)準(zhǔn)備完成后自動觸發(fā)下一個動作而不是等待數(shù)據(jù)完成。這種思想再結(jié)合異步化編程使得我們在統(tǒng)一線程模型,降低多線程編程成本的同時提升整個系統(tǒng)的吞吐量。

閑魚當(dāng)前的業(yè)務(wù)場景本身足夠復(fù)雜,然而目前大規(guī)模使用的仍然是阻塞式編程,每個業(yè)務(wù)場景的流程被串行同步執(zhí)行。它最大的問題在于大量線程等待IO(日志記錄,RPC調(diào)用,HTTP請求等)完成。有鑒于此,閑魚引入RxJava 2.0來作為響應(yīng)式編程框架對應(yīng)用進(jìn)行異步化改造。目前app內(nèi)的魚塘首頁,留言列表以及魚塘詳情已經(jīng)完成異步化改造并上線。

響應(yīng)式異步化編程實踐

異步化編程不同于傳統(tǒng)的阻塞式編程,他們的區(qū)別可以用下面的圖來表達(dá),C代表computation任務(wù),I代表IO任務(wù)。原來的一個線程中執(zhí)行完所有的computation和IO任務(wù)轉(zhuǎn)變成現(xiàn)在computation和IO任務(wù)分離,這樣做的好處是CPU只關(guān)注computation任務(wù),理論上CPU核數(shù)個線程就能滿足所有的computation任務(wù),大大減少線程切換開銷。

線程模型 RxJava框架背后是線程模型的演進(jìn)。在引入RxJava前傳統(tǒng)Java自帶多線程框架(Executor)和異步Future,它們的問題在于

  • 線程池?zé)o法統(tǒng)一。開發(fā)在自己的場景下都可能去定義線程池。

  • 上下文切換。隨著線程數(shù)的增多,線程上下文的切換必然增多。

  • Future異步方式仍然是一種阻塞等待式方法。

RxJava結(jié)合全異步編程方式的優(yōu)勢在于

  • 線程利用率大幅提高。當(dāng)線程需要做阻塞操作時及時切換避免長時間占有線程,整個流程無阻塞。

  • RxJava統(tǒng)一了線程池模型。我們可以根據(jù)不同的場景選擇對應(yīng)的線程調(diào)度模型。

  • 極致線程模型變得可能。理論上只需要cpu核數(shù)個線程就可以運(yùn)行所有computation任務(wù),這意味線程切換帶來的開銷幾乎被消除。

應(yīng)用改造

響應(yīng)式全異步編程天生拒絕阻塞,任何阻塞點都可能導(dǎo)致性能的退步。更嚴(yán)重的如果我們控制了線程數(shù),當(dāng)任務(wù)因為阻塞而產(chǎn)生堆積,隨著堆積的任務(wù)變多應(yīng)用會gc影響線上服務(wù)。目前閑魚應(yīng)用中存在4類阻塞點

  • 應(yīng)用日志。

  • HTTP請求。

  • RPC調(diào)用。

  • 緩存讀寫。

閑魚中的日志不僅僅作為異常輸出手段,也是數(shù)據(jù)統(tǒng)計的一個主要方法。因為日志的性能顯得很重要。雖然log4j和logback都提供了異步方式,但是它們本質(zhì)上還是基于鎖來實現(xiàn)。log4j2是新一代的基于LMAX Disruptor的無鎖異步日志系統(tǒng),在多線程程序中,其吞吐量比log4j和logback高10倍左右。

而HTTP,RPC以及緩存的讀寫都需要改造成純異步方式:當(dāng)請求發(fā)生時線程被釋放,請求完成后繼續(xù)在新的線程中執(zhí)行余下業(yè)務(wù)流程。

執(zhí)行范式

對閑魚中的場景進(jìn)行一下歸納,可以梳理出三種執(zhí)行范式,下面會分別簡單展示這三種范式。為了簡單起見,其中涉及到的IO操作都用一個函數(shù)加以抽象。

串行請求以常用的電商場景為例,查看我買的商品詳情。業(yè)務(wù)流程上要先查詢訂單詳情,然后從訂單詳情中拿到商品,最后根據(jù)商品去查詢商品詳情。

并發(fā)請求商品詳情中往往還會有一些額外的信息,比如瀏覽量以及留言內(nèi)容。瀏覽量和留言它們彼此是互不依賴的,但是都依賴查到的商品信息。

更新緩存熱門商品詳情往往意味高并發(fā)訪問,我們可以將這些數(shù)據(jù)緩存來減輕數(shù)據(jù)庫的壓力。但是緩存成功與否都不影響本次請求(緩存失敗導(dǎo)致下次請求仍然走db,本次請求的數(shù)據(jù)仍然返回給用戶)。更新緩存本質(zhì)上代表這樣一類操作,它們在請求完成后執(zhí)行一些額外的操作(緩存,通知用戶,日志記錄等),這些額外操作的成功與否不對主流程造成任何影響。

需要強(qiáng)調(diào)的是上面流中所有的方法都對應(yīng)著一次IO操作(RPC,緩存讀寫等),這些IO操作都應(yīng)該是全異步方式實現(xiàn)(不能等待IO完成,而是IO完成后主動喚醒)。幸運(yùn)的是已經(jīng)有一些第三方庫來幫我們完成這些IO異步化。

改造結(jié)果

我們對改造完的接口進(jìn)行了一輪性能測試,分別從接口rt,線程數(shù)以及cpu利用率三個方面對阻塞式執(zhí)行和響應(yīng)式純異步方式進(jìn)行對比

rt因為我們在異步方式中增加了并行操作, 所以rt降低是必然的,rt下降50%左右。當(dāng)請求QPS達(dá)到650的時候,傳統(tǒng)阻塞方式rt飆升,服務(wù)開始不可用;響應(yīng)式純異步方式rt較為穩(wěn)定,QPS達(dá)到850的時候開始明顯上漲。

線程數(shù)阻塞式執(zhí)行方式因為在IO發(fā)生時線程會等待IO完成,而異步方式下線程直接釋放,所以異步方式下線程利用效率明顯更高。下面的測試結(jié)果也表面異步方式的線程數(shù)一直較為穩(wěn)定;阻塞模式下線程在QPS到達(dá)650時被耗盡,這意味著新的請求將被直接拒絕。

CPU由于異步模式下我們增加了并發(fā),因此CPU使用必然會較阻塞模式高,測試結(jié)果也說明了這一點。然而當(dāng)QPS到達(dá)650的時候,阻塞模式下服務(wù)已經(jīng)不可用,因此CPU利用率最高只能到達(dá)75%左右;而異步模式CPU能夠到達(dá)97%。

總結(jié)

本文介紹了響應(yīng)式編程在閑魚的應(yīng)用現(xiàn)狀,我們選用了RxJava作為響應(yīng)式編程框架,并選取了閑魚留言列表,魚塘首頁以及魚塘詳情頁進(jìn)行改造并進(jìn)行了性能測試。測試數(shù)據(jù)表明閑魚群聊首頁場景下,在rt降低50%的同時整個系統(tǒng)的吞吐量能提升約30%。

目前響應(yīng)式純異步編程在閑魚仍然處于起步階段,我們的線程池模型仍然沒法做到極致(暫時沒法完全消除阻塞點)。接下來會朝著極致線程模型進(jìn)行嘗試,可能的改造點包括

  • 阻塞點消除。

  • cpu核數(shù)個線程來調(diào)度所有的computation任務(wù)。

  • 底層的IO線程模型統(tǒng)一。現(xiàn)在IO操作(RPC,HTTP,緩存)都是各自維護(hù)自己的線程池,理論上這些線程池都可以趨于統(tǒng)一。

聯(lián)系我們

如果對文本的內(nèi)容有疑問或指正,歡迎告知我們。

閑魚技術(shù)團(tuán)隊是一只短小精悍的工程技術(shù)團(tuán)隊。我們不僅關(guān)注于業(yè)務(wù)問題的有效解決,同時我們在推動打破技術(shù)棧分工限制(android/iOS/Html5/Server 編程模型和語言的統(tǒng)一)、計算機(jī)視覺技術(shù)在移動終端上的前沿實踐工作。作為閑魚技術(shù)團(tuán)隊的軟件工程師,您有機(jī)會去展示您所有的才能和勇氣,在整個產(chǎn)品的演進(jìn)和用戶問題解決中證明技術(shù)發(fā)展是改變生活方式的動力。

簡歷投遞: [email protected]

識別二維碼,前瞻技術(shù)盡在掌握

 

來自:https://mp.weixin.qq.com/s/7-h2w_iXrM5861iGTpftNQ

 

標(biāo)簽: 電商 數(shù)據(jù)庫

版權(quán)申明:本站文章部分自網(wǎng)絡(luò),如有侵權(quán),請聯(lián)系:west999com@outlook.com
特別注意:本站所有轉(zhuǎn)載文章言論不代表本站觀點!
本站所提供的圖片等素材,版權(quán)歸原作者所有,如需使用,請與原作者聯(lián)系。

上一篇:Google 升級關(guān)鍵云數(shù)據(jù)庫服務(wù)

下一篇:SpringBoot | 第十章:Swagger2的集成和使用