<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    放翁(文初)的一畝三分地

      BlogJava :: 首頁 :: 新隨筆 :: 聯(lián)系 :: 聚合  :: 管理 ::
      210 隨筆 :: 1 文章 :: 320 評(píng)論 :: 0 Trackbacks
     

    Author:放翁(文初)

    Date: 2010/9/9

    Email:fangweng@taobao.com

    圍脖: http://t.sina.com.cn/fangweng

             有段時(shí)間沒有更新技術(shù)blog了,現(xiàn)在有空每天都寫寫圍脖,記錄生活和工作的點(diǎn)滴,但是有時(shí)候發(fā)現(xiàn)有些技術(shù)的想法和工作總結(jié)沒有像過去那么完整的寫很大一篇,但是也有零零散散的不少點(diǎn)滴,因此想著隨意的寫這么一個(gè)連續(xù)的片段分享。

             為什么叫做代碼背后的點(diǎn)滴呢,其實(shí)在現(xiàn)在互聯(lián)網(wǎng)應(yīng)用來說,其實(shí)用什么語言,用什么平臺(tái)有些場(chǎng)景有影響,但已經(jīng)不是絕對(duì)重要的因素的,其實(shí)代碼被后的設(shè)計(jì)思想才是最重要的。而用最熟悉的方式去表現(xiàn)最自然的想法,那才能做到游刃有余,就好比我向華黎同學(xué)申請(qǐng)這次內(nèi)部獎(jiǎng)勵(lì)的獎(jiǎng)品希望是手寫筆,因?yàn)椴徽撌裁串媹D工具用起來都會(huì)妨礙我的順暢的表達(dá),最終我把注意力集中到了畫本身上,而丟失了應(yīng)有的靈感(在沒有拿到畫筆前,最近先少畫點(diǎn)圖)。寫代碼也是一樣,不要被流行,高性能,有潛力這些詞搞丟了自己的目標(biāo),工具就是工具,能廣泛的去學(xué),但不必要廣泛的用,把干活要用的那門搞熟練了再說。廢話不多說,言歸正傳。

             先說一下,以下的任何觀點(diǎn)都必須“對(duì)癥下藥”,沒啥萬能靈丹妙藥,怎么用,什么時(shí)候用是關(guān)鍵。

    聚與散:

             場(chǎng)景一,在分享時(shí)談到Jetty7整個(gè)體系架構(gòu)就一個(gè)線程資源池,為什么?整個(gè)jetty體系都是事件驅(qū)動(dòng)模式(包括系統(tǒng)事件:NIO事件,包括業(yè)務(wù)事件:request suspend),我們系統(tǒng)很多時(shí)候有很多資源池(線程,DB,服務(wù))等等,有些是直接的,有些是間接的(依賴于第三方包引入的)。我們要求每個(gè)開發(fā)者都要給資源池設(shè)置上限,給隊(duì)列限定長(zhǎng)度,防止崩潰,但是當(dāng)這些資源池散落在各個(gè)地方的時(shí)候,那么每一個(gè)資源達(dá)到邊界以前,總和可能已經(jīng)超過了系統(tǒng)負(fù)載能力,那么一樣會(huì)奔潰。因此資源的統(tǒng)一規(guī)劃看來有必要,那可以考慮將物理隔離變成邏輯隔離(防止業(yè)務(wù)干擾,同時(shí)可以根據(jù)權(quán)重模型來動(dòng)態(tài)分配和預(yù)留資源),另一方面整個(gè)小團(tuán)隊(duì)到大團(tuán)隊(duì),對(duì)于連接池的使用抽象出來以后,那么多個(gè)依賴都可以在抽象的基礎(chǔ)上公用一個(gè)物理資源池,如果引入第三方緩存,都可以將資源策略應(yīng)用到多機(jī)上。回過來,這里就要說聚和散的關(guān)系,聚能夠在一定程度上有全局觀,同時(shí)可以根據(jù)策略模型來調(diào)配資源,散最大的好處就是業(yè)務(wù)隔離,互相不會(huì)影響。最近在寫一個(gè)線程資源分配的小東西,目標(biāo)就是:資源可根據(jù)權(quán)重模型分配。(權(quán)重模型兩條:設(shè)定某一類key獲取資源可以保留一定資源獨(dú)享,設(shè)定某一類key獲取資源最大上限可控)其實(shí)這就是一個(gè)邏輯隔離資源的最基本的雛形。

             場(chǎng)景二,有同學(xué)談起他們的系統(tǒng)屬于消耗CPU類型的應(yīng)用,特別是對(duì)數(shù)據(jù)庫獲取到的數(shù)據(jù)作處理和渲染的時(shí)候,問有啥好的建議。我的建議是數(shù)據(jù)獲取端沒啥可優(yōu)化的話,考慮數(shù)據(jù)存入端增加數(shù)據(jù)預(yù)處理功能,將數(shù)據(jù)處理的壓力分?jǐn)偟礁嘁矓?shù)據(jù)存入方。當(dāng)然這個(gè)代價(jià)是數(shù)據(jù)的可復(fù)用性降低,業(yè)務(wù)邏輯侵入到其他系統(tǒng),數(shù)據(jù)存入方性能會(huì)有所下降(如果這三點(diǎn)不足以影響業(yè)務(wù)流程和數(shù)據(jù)存入方,那么可做)。其實(shí)這是聚和散的另一種表現(xiàn),很多時(shí)候需要考慮的是全局優(yōu)化,而不是局部?jī)?yōu)化。

             場(chǎng)景三,我今天看了淘寶Tair的作者若海介紹關(guān)于tair的一些設(shè)計(jì)思路的文章,這和早先我做memcached的客戶端思想是有共同點(diǎn)的。首先就是數(shù)據(jù)的獲取從服務(wù)端中轉(zhuǎn)路由變成了客戶端獲得配置本地hash選擇目標(biāo)服務(wù)器,這就將服務(wù)路由的功能客戶端化了,避免了單點(diǎn)的瓶頸,也提高了訪問性能。同時(shí)metadata的數(shù)據(jù)保存在configserver中,以弱依賴的方式主動(dòng)推送,避免客戶端受到影響。但他的設(shè)計(jì)里面數(shù)據(jù)同步是服務(wù)端做的,而我當(dāng)年是客戶端做的(隊(duì)列中異步備份),當(dāng)時(shí)一方面是沒有辦法去改服務(wù)端的memcached,另一方面服務(wù)端能有多少,客戶端有多少,這些壓力的分?jǐn)?,天然的緩解服?wù)端的壓力,將壓力分散在了客戶端上。(代價(jià)就是客戶端工作多一點(diǎn),即時(shí)性依賴于各個(gè)客戶端的能力)這也是一種散。

        場(chǎng)景四,TOP大數(shù)據(jù)請(qǐng)求的處理設(shè)計(jì),TOP的目標(biāo)是什么?大壩。主要職能:限流,授權(quán),路由。那么路由這件事情必須在TOP走么,數(shù)據(jù)交互和平臺(tái)校驗(yàn)是否一定要在一個(gè)流程中完成,其實(shí)不然,安全校驗(yàn)通過以后可以頒發(fā)會(huì)話標(biāo)識(shí)和目標(biāo)服務(wù)地址,直接由客戶端和服務(wù)端交互。(這其實(shí)就和很多分布式文件系統(tǒng)或者分布式緩存系統(tǒng)一樣的考慮,校驗(yàn)通過后就直接建立數(shù)據(jù)通道進(jìn)行數(shù)據(jù)交互,避免性能受到影響),這了的聚和散就涉及到業(yè)務(wù)的耦合性分析決定流程的聚散,改善性能和穩(wěn)定性。

       場(chǎng)景五,上面談到過最近自己實(shí)現(xiàn)資源分配邏輯隔離的這樣的資源池,現(xiàn)在就是做線程池,起初不想用jdk自帶的線程池,原因是自帶線程池啟動(dòng)線程后,線程只要在coresize內(nèi)就不會(huì)被銷毀,也沒有調(diào)度來從池里面獲取執(zhí)行任務(wù),完成任務(wù)放回到資源池,這些線程就輪訓(xùn)的去獲取隊(duì)列的數(shù)據(jù)。好處在于沒有一個(gè)manager的管理性能和復(fù)雜度會(huì)提升,缺點(diǎn)就是資源分配就無法實(shí)現(xiàn)。其實(shí)這就是典型的一種資源分配有一個(gè)實(shí)例主導(dǎo)還是由多個(gè)消費(fèi)者自己主導(dǎo)的設(shè)計(jì)。

    強(qiáng)弱依賴

             場(chǎng)景:JettyContinuation設(shè)計(jì)中,從調(diào)用suspend方法來懸掛起請(qǐng)求,避免退出容器service方法reqres被回收,到業(yè)務(wù)主動(dòng)調(diào)用complete結(jié)束請(qǐng)求流程,回寫數(shù)據(jù)到客戶端,都采用產(chǎn)生事件,異步的由核心線程池去執(zhí)行。這樣業(yè)務(wù)線程池的線程生命周期就不會(huì)受到系統(tǒng)線程輸出快慢或者容器本身壓力的影響。這種弱依賴能夠極大的解耦兩個(gè)系統(tǒng)的服務(wù)能力和穩(wěn)定性。

    關(guān)鍵先生

             場(chǎng)景一,有同學(xué)一個(gè)壓力測(cè)試報(bào)告中做了這么一個(gè)測(cè)試,整個(gè)事務(wù)處理流程第一步驟消耗CPU,第二步驟消耗IO。整體事務(wù)時(shí)間=CPU 10 ms + IO 90 ms。他考慮是否能夠通過縮短IO消耗時(shí)間或者CPU消耗時(shí)間來提升RT時(shí)間,就能夠提升TPS。他的結(jié)果是IO提升一倍TPS沒有任何變化,CPU消耗時(shí)間提升一倍,TPS翻番。這能說明啥,說明瓶頸在CPU上,提升一倍,那么處理能力增加一倍(就好比資源池內(nèi)的資源生命周期縮短,被利用的次數(shù)更多),大部分請(qǐng)求都在CPU上排隊(duì)等待處理,因此系統(tǒng)的TPS取決于瓶頸資源的處理能力而不是簡(jiǎn)單的縮短RT就可以改變的。(貼切的比喻就是漏斗,不論你大口朝上或者朝下,小口決定了水流量,小口就是那個(gè)關(guān)鍵先生)

             場(chǎng)景二,異步化壓力測(cè)試的結(jié)果中有如下一組結(jié)果:

    容器

    請(qǐng)求服務(wù)

    請(qǐng)求處理模式

    TPS

    Nginx + Jetty

    Time.get

    同步

    1534

    Nginx + Jetty

    Time.get

    異步

    1068

    Nginx + Jetty

    User.get

    同步

    1060

    Nginx + Jetty

    User.get

    異步

    1027

           








           Time.get是不向后中轉(zhuǎn)服務(wù)的模擬請(qǐng)求,也就是服務(wù)端很快就響應(yīng)給客戶端了,而user.get是真實(shí)模擬服務(wù)向后請(qǐng)求,有一定消耗。但看這個(gè)結(jié)果,同樣是同步和異步對(duì)比,前者性能相差很大,后者相差不大。原因?異步一定有消耗,但這個(gè)消耗占整體事務(wù)處理時(shí)間的比例是多少,這就會(huì)放大影響。而TOP大部分服務(wù)都要比user.get更加耗時(shí),因此后面才是線上的真實(shí)狀況。(因此場(chǎng)景模擬是壓力測(cè)試最重要的條件),這里的關(guān)鍵先生還是要看整個(gè)事務(wù)處理的消耗點(diǎn)。衍生一下上次電話面試的一個(gè)北京的朋友,談到了NIO,問了他是否做過BIONIO的測(cè)試比較,什么時(shí)候用NIO最好,他還真做過四類測(cè)試,有結(jié)果,但還是沒搞明白為什么:1.傳輸數(shù)據(jù)量大,后端服務(wù)處理慢。2.傳輸數(shù)據(jù)量大,后端服務(wù)處理快。3.傳輸數(shù)據(jù)量小,后端服務(wù)處理慢。4.傳輸數(shù)據(jù)量小,后端處理速度快。結(jié)果是NIO4處于劣勢(shì)。其實(shí)BIO釋放的夠快,那么NIO的異步在整體事務(wù)處理消耗就形成了劣勢(shì)。

    生命周期

             場(chǎng)景:在異步分享過程中,談到了事件驅(qū)動(dòng)的架構(gòu)設(shè)計(jì)。原來的流程可以分成很多個(gè)步驟,每一個(gè)步驟由于處理的需要都會(huì)申請(qǐng)必要的資源,不同步驟有些是共享資源,有些是不共享的,那么從資源的生命周期角度來說,一個(gè)流程中所有資源的生命周期都是一樣,就是整個(gè)業(yè)務(wù)事務(wù)的執(zhí)行周期,對(duì)于在一個(gè)業(yè)務(wù)流程中各個(gè)步驟很少共享資源的狀況,或者有等待外部返回內(nèi)容的情況時(shí),切割開流程步驟,降低資源生命周期,提升資源利用率,是事件驅(qū)動(dòng)的最大優(yōu)勢(shì)。NIO如此,Servlet3規(guī)范如此。簡(jiǎn)單來說就是:按需分配。另一方面我們也能看到,處理都是無狀態(tài)的,只有輸入和輸出,無狀態(tài)的處理更容易復(fù)用??雌饋磉@種設(shè)計(jì)很好,但其實(shí)背后還是有不少問題:1.流程復(fù)雜化,原來通過程序保證流程的順序和依賴,現(xiàn)在切割以后,如何驅(qū)動(dòng),順序如何保證,如何容錯(cuò),都給系統(tǒng)增加很大的維護(hù)成本。2.異步化后消耗時(shí)間必然增大,不論是通過pull主動(dòng)獲取狀態(tài)變更還是通過push被通知到,都在性能和時(shí)間消耗上會(huì)有一些付出。因此還是需要依環(huán)境而定。

    瓶頸移動(dòng)

             場(chǎng)景一,還是一個(gè)同學(xué)的優(yōu)化的案例,當(dāng)時(shí)談到有個(gè)叫做最佳線程數(shù),但是覺得在優(yōu)化過程中最佳線程數(shù)是在變化的,其實(shí)很多時(shí)候當(dāng)你覺得任何的結(jié)論是不穩(wěn)定的,那么你需要進(jìn)一步深入挖掘下去。其實(shí)之所以最佳線程數(shù)這個(gè)值不穩(wěn)定,關(guān)鍵在于我們?nèi)绾稳?yōu)化,找到問題所在。和前面舉例一樣,系統(tǒng)可以看成各種類型資源池的一個(gè)整體,然后由很多個(gè)步驟不斷申請(qǐng)資源來完成各個(gè)步驟,最后返回結(jié)果。那么說白了,哪個(gè)資源池是流程中處理能力最弱的,他就是問題所在,就是瓶頸,但是通過優(yōu)化后這個(gè)瓶頸可能有所改善,與此同時(shí)另一個(gè)資源成為漏斗的小口,這時(shí)候,瓶頸移動(dòng)了,優(yōu)化的預(yù)期結(jié)果和提升的瓶頸點(diǎn)性能就不吻合了。所以,把帶寬,CPU,IO,外部服務(wù),DBWeb線程池等等都看成資源池,找到瓶頸所在去優(yōu)化,同時(shí)在優(yōu)化過程中不斷修正優(yōu)化目標(biāo),達(dá)到最后全局優(yōu)化的效果。

             場(chǎng)景二,異步化分享中談到一點(diǎn),異步化要有全局觀。例如A依賴與B系統(tǒng),組成了一個(gè)完整的服務(wù)體系,通過異步化方式將A的資源生命周期縮短到只有A處理的時(shí)間,B的資源生命周期就是B的處理時(shí)間,此時(shí)如果A是原有整個(gè)系統(tǒng)的瓶頸,那么就會(huì)產(chǎn)生雪中送炭的效果,系統(tǒng)整體性能會(huì)有所提高(大部分情況下,原因看后面介紹)。如果B是瓶頸,那么就是雪上加霜,更多的水流被放進(jìn)來,如果B自身沒有流量控制,那么系統(tǒng)就會(huì)處于不健康的狀況,甚至奔潰,系統(tǒng)的整體RT時(shí)間可能會(huì)增加(A節(jié)省的時(shí)間小于B增加的時(shí)間)。因此這就是系統(tǒng)間瓶頸移動(dòng)產(chǎn)生的影響,同樣也和一個(gè)系統(tǒng)一樣,考慮優(yōu)化一定是整體性的考慮,否則問題不會(huì)朝著預(yù)期的方向解決。

             晚了晚了,休息,希望這些對(duì)大家有幫助。

    posted on 2010-09-09 02:05 岑文初 閱讀(4293) 評(píng)論(8)  編輯  收藏

    評(píng)論

    # re: 代碼背后的點(diǎn)滴 2010-09-11 15:38 xzs
    你每天這是在晚上12點(diǎn)以后睡覺,早上9點(diǎn)前去公司嗎?  回復(fù)  更多評(píng)論
      

    # re: 代碼背后的點(diǎn)滴 2010-09-11 15:39 xzs
    你每天都是在晚上12點(diǎn)以后睡覺,早上9點(diǎn)前去公司嗎?  回復(fù)  更多評(píng)論
      

    # re: 代碼背后的點(diǎn)滴 2010-09-11 16:18 xzs
    使用java -Xmx2048啟動(dòng)jvm
    請(qǐng)教一個(gè)問題,jvm創(chuàng)建一個(gè)線程時(shí),線程本身使用的內(nèi)存是該jvm的內(nèi)存(2G范圍內(nèi))還是操作系統(tǒng)的內(nèi)存?
    如果是使用操作系統(tǒng)的內(nèi)存,為什么?這一點(diǎn)有點(diǎn)疑惑。  回復(fù)  更多評(píng)論
      

    # re: 代碼背后的點(diǎn)滴 2010-09-11 23:10 岑文初
    線程的棧數(shù)據(jù)是jvm自己的,要不然也不會(huì)有啟動(dòng)太多線程導(dǎo)致OOM或者棧溢出的問題了@xzs
      回復(fù)  更多評(píng)論
      

    # re: 代碼背后的點(diǎn)滴 2010-09-11 23:11 岑文初
    一般盡量不會(huì)太晚,超過12點(diǎn)太多時(shí)間,早晨6點(diǎn)多肯定起來了@xzs
      回復(fù)  更多評(píng)論
      

    # re: 代碼背后的點(diǎn)滴 2010-09-13 21:47 楊國(guó)利
    @岑文初,
    文初,我回答一下這個(gè)網(wǎng)友的問題:
    使用java -Xmx2048啟動(dòng)jvm
    請(qǐng)教一個(gè)問題,jvm創(chuàng)建一個(gè)線程時(shí),線程本身使用的內(nèi)存是該jvm的內(nèi)存(2G范圍內(nèi))還是操作系統(tǒng)的內(nèi)存?
    如果是使用操作系統(tǒng)的內(nèi)存,為什么?這一點(diǎn)有點(diǎn)疑惑。

    首先第一點(diǎn):ivm創(chuàng)建線程是使用了自己的內(nèi)存,但是同時(shí)你也得注意,JVM在給這個(gè)線程分配資源的時(shí)候,操作系統(tǒng)本身也會(huì)分配一定的空間。舉個(gè)例子:大家都知道windows給一個(gè)進(jìn)程分配的最大內(nèi)存空間是2G,當(dāng)我們?cè)趈vm中最大分配了2G的空間,線程增多,空間不夠用,是jvm的空間不夠,有的時(shí)候還真不是,是操作系統(tǒng)分配的空間不夠了。這個(gè)也得慢慢調(diào)試和增加tomcat的進(jìn)程數(shù)量來解決這個(gè)問題。就說這么多。
      回復(fù)  更多評(píng)論
      

    # re: 代碼背后的點(diǎn)滴 2010-09-14 20:26 xzs
    你不收郵件嗎?  回復(fù)  更多評(píng)論
      

    # re: 代碼背后的點(diǎn)滴 2010-09-16 17:04 君楚
    關(guān)于異步和資源自制的思路。我最近也在思考。

    覺得以前設(shè)計(jì)的系統(tǒng)都是死的。一個(gè)高可靠的系統(tǒng),就像一個(gè)生物體一樣。簡(jiǎn)單說就是自治的。需要做到自治,就涉及到很多隔離和資源管理的機(jī)制。恰恰,異步能解決交互方面的自治問題。像你提到的邏輯隔離,物理統(tǒng)一的思路,就是另一種解決資源自治的方式。

    穩(wěn)定的系統(tǒng),內(nèi)部應(yīng)該是有自己的脈搏的,不會(huì)因?yàn)橥饨绲挠绊懚騺y。思路有些混亂,有感而發(fā)。博主總結(jié)的很好,對(duì)我啟發(fā)很大,計(jì)劃后續(xù)了解一下Jetty架構(gòu)。  回復(fù)  更多評(píng)論
      


    只有注冊(cè)用戶登錄后才能發(fā)表評(píng)論。


    網(wǎng)站導(dǎo)航:
    博客園   IT新聞   Chat2DB   C++博客   博問  
     
    主站蜘蛛池模板: 一区二区三区免费电影| 人人狠狠综合久久亚洲88| 亚洲AV无码国产精品麻豆天美| 无码人妻精品一二三区免费| 亚洲色一色噜一噜噜噜| 无码天堂亚洲国产AV| 24小时日本在线www免费的| 久久精品国产亚洲av麻豆图片| 免费网站看av片| 亚洲视频在线视频| 在线a免费观看最新网站| 亚洲国产一区二区a毛片| 久久国产精品免费看| 亚洲视频小说图片| 久久久久久99av无码免费网站| 亚洲国产精品白丝在线观看| 成人AV免费网址在线观看| 亚洲一区二区久久| 国产美女a做受大片免费| 国产精品亚洲а∨无码播放麻豆 | 日韩毛片免费无码无毒视频观看 | 日韩版码免费福利视频| 亚洲午夜精品在线| 国产又大又粗又硬又长免费| 18禁亚洲深夜福利人口| 亚洲一区二区三区无码中文字幕| 国产午夜无码片免费| 亚洲人成免费电影| 免费的涩涩视频在线播放| 国产精品偷伦视频免费观看了| 久久久亚洲欧洲日产国码是AV| 日本妇人成熟免费中文字幕| 在线观看亚洲专区| 亚洲综合久久1区2区3区| 亚洲国产一成久久精品国产成人综合 | 又粗又大又黑又长的免费视频| 美女无遮挡免费视频网站| 无码乱人伦一区二区亚洲| 精品久久洲久久久久护士免费| 中国一级特黄的片子免费 | 一二三四在线观看免费高清中文在线观看|