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

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

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

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

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

    Author:放翁(文初)

    Date: 2010/11/23

    Email:fangweng@taobao.com

    mblog: http://t.sina.com.cn/fangweng

    blog: http://blog.csdn.net/cenwenchu79/

             這篇文章將會(huì)從問(wèn)題,技術(shù)背景,設(shè)計(jì)實(shí)現(xiàn),代碼范例這些角度去談基于管道化和事件驅(qū)動(dòng)模型的Web請(qǐng)求處理,其中的一些描述和例子也許不是很恰當(dāng),也希望得到更多的反饋。

     

    業(yè)務(wù)架構(gòu)設(shè)計(jì):

             基于上述問(wèn)題,通過(guò)兩步走來(lái)解決。首先采用支持打破傳統(tǒng)http request生命周期管理的Web容器(很多人說(shuō)可以自己寫(xiě),其實(shí)Web容器寫(xiě)起來(lái)并不是最麻煩的,如何做好兼容和照顧好每一個(gè)細(xì)節(jié)才是漫長(zhǎng)發(fā)展的道路)。其次在容器新的線程生命周期管理基礎(chǔ)上封裝業(yè)務(wù)框架,為開(kāi)發(fā)者屏蔽底層異步化和事件驅(qū)動(dòng)模式帶來(lái)的復(fù)雜流程管理內(nèi)容。

                                                     

    Pipe Service Framework

    基礎(chǔ)管道體系:

             很多時(shí)候設(shè)計(jì)和實(shí)現(xiàn)都會(huì)有很多細(xì)節(jié)上的差異,而這些差異往往是在事實(shí)驗(yàn)證后對(duì)體系的一種修訂,也許修訂后的結(jié)構(gòu)不如修訂前的清晰和優(yōu)雅,但是確實(shí)在性能和結(jié)構(gòu)上找到了平衡點(diǎn),下面就看看兩個(gè)基礎(chǔ)管道體系的設(shè)計(jì),后一個(gè)是前一個(gè)的演進(jìn)。

                                                        

    流程與角色說(shuō)明:

             角色分成:Container(傳統(tǒng)的容器)dispatcher(任務(wù)派發(fā)線程數(shù)量根據(jù)性能要求可以是1-m個(gè)),job pool(存儲(chǔ)任務(wù)數(shù)據(jù)的本地緩存),event queue(任務(wù)狀態(tài)發(fā)生變化的事件存儲(chǔ)隊(duì)列),pipe register center(管道鏈注冊(cè)中心,根據(jù)job的自描述信息給出相關(guān)處理的單個(gè)管道或者管道鏈),thread pool(用于處理業(yè)務(wù)請(qǐng)求的線程池)

             流程描述如下:

    1. 容器解析請(qǐng)求數(shù)據(jù)。

    2. 創(chuàng)建任務(wù)并存儲(chǔ)到job pool

    3. 發(fā)送job執(zhí)行消息到消息隊(duì)列。

    4. 釋放容器線程,掛起請(qǐng)求資源。

    5. Dispatcher阻塞方式的從event queue獲取事件消息。

    6. 如果是刪除任務(wù)事件消息,則將剩余未發(fā)送數(shù)據(jù)flush到客戶端,結(jié)束本次Http會(huì)話。(刪除任務(wù)消息是在任務(wù)走完所有管道或者任務(wù)執(zhí)行超時(shí)或者任務(wù)執(zhí)行失敗產(chǎn)生)

    7. 如果是執(zhí)行任務(wù)消息事件,則從job pool獲取任務(wù)數(shù)據(jù)。

    8. 根據(jù)任務(wù)信息去pipe register center獲取pipe或者pipe chain

    9. 將任務(wù)數(shù)據(jù)和管道信息發(fā)送給線程池。

    10.              線程池分配線程執(zhí)行任務(wù),如果當(dāng)前pipe chain執(zhí)行后并沒(méi)有完成job,則將job信息存儲(chǔ)到job pool。(這塊后面可以參看一下job 執(zhí)行邏輯圖)

    11.              如果沒(méi)有執(zhí)行完畢,則可以創(chuàng)建一個(gè)或者多個(gè)執(zhí)行事件激發(fā)下一次的處理,如果執(zhí)行完畢,則創(chuàng)建一個(gè)刪除任務(wù)消息激發(fā)任務(wù)結(jié)束處理。

    問(wèn)題:

    1. 規(guī)范化帶來(lái)的消息事件過(guò)多,線程切換消耗的問(wèn)題。

    2. Dispatcher自身任務(wù)是否繁重導(dǎo)致處理速度變慢。同時(shí)兩套線程池管理麻煩(如果Dispatcher的個(gè)數(shù)為M也就可以看作另一個(gè)線程池)。

    細(xì)節(jié):

    1. 利用容器本身支持請(qǐng)求掛起的方式,將容器線程池和業(yè)務(wù)線程池分割開(kāi)來(lái)。

    2. 如果所有子任務(wù)都是串行化且沒(méi)有一個(gè)子任務(wù)是由外部系統(tǒng)來(lái)實(shí)施狀態(tài)遷移,則可以在一個(gè)線程中完成所有子任務(wù),減少線程切換和事件分發(fā)帶來(lái)的消耗。最極端是退化到任務(wù)交由容器線程一并完成。

    3. 當(dāng)允許并行多個(gè)子任務(wù)執(zhí)行時(shí),只需要在并行子任務(wù)執(zhí)行前的那個(gè)任務(wù)完成后,分發(fā)多個(gè)任務(wù)執(zhí)行事件,并且任務(wù)執(zhí)行事件指定要求處理的Pipe,就可以讓分發(fā)器將當(dāng)前任務(wù)分發(fā)給多個(gè)線程并行執(zhí)行子任務(wù),后續(xù)詳細(xì)介紹子任務(wù)并行處理的過(guò)程。

    4. Job會(huì)被多線程訪問(wèn),因此必要的屬性需要做成線程安全的。另一種模式就是抓取job的數(shù)據(jù)是個(gè)快照(clone),在結(jié)果產(chǎn)生后再鎖住合并。


                                                  


    角色和流程說(shuō)明:

             上圖角色將線程池和消息隊(duì)列做了合并,去掉了dispatcherevent queue合并到了 Thread Pool中。

    1. 容器解析請(qǐng)求參數(shù)。

    2. 創(chuàng)建任務(wù)并放置到任務(wù)緩存中。

    3. 發(fā)送執(zhí)行任務(wù)事件到線程池。

    4. 釋放容器線程資源。

    5. 線程池從自身事件隊(duì)列中獲取事件。

    6. 如果是刪除事件,則直接刪除任務(wù),并發(fā)送數(shù)據(jù)到客戶端,結(jié)束本地會(huì)話。

    7. 如果是執(zhí)行事件,則從pipe register center獲取pipe或者pipe chain

    8. 本地執(zhí)行pipe或者pipe chain

    9. 更新job 數(shù)據(jù)到緩存。

    10.              創(chuàng)建執(zhí)行或者刪除消息事件到本地線程池隊(duì)列或者直接連續(xù)執(zhí)行。

    差異:

    1. 將分發(fā)器的功能散落到各個(gè)實(shí)際業(yè)務(wù)操作線程上,提升處理效率。(增加了對(duì)于消息隊(duì)列的競(jìng)爭(zhēng),不過(guò)這個(gè)代價(jià)不是很大)

    2. 線程可以連續(xù)執(zhí)行子任務(wù),減少任務(wù)事件數(shù)量,減少線程切換代價(jià)。(類似于自旋鎖的方式,自己可以盡量的完成可以完成的任務(wù),帶來(lái)的問(wèn)題就是對(duì)于不同任務(wù)多階段并行執(zhí)行的策略有所減弱)

    細(xì)節(jié):

             和第一種模式一樣,可以退化這個(gè)模型到傳統(tǒng)的一個(gè)web容器線程處理所有的子任務(wù),減少線程切換代價(jià)。

    四種方式的子任務(wù)執(zhí)行說(shuō)明:

                                                

    傳統(tǒng)的串行化任務(wù)執(zhí)行模式,這種模式下可以交由單個(gè)線程全部執(zhí)行,減少線程切換代價(jià),另一方面假如3這個(gè)環(huán)節(jié)將會(huì)等待外部系統(tǒng)來(lái)更新?tīng)顟B(tài)并繼續(xù)執(zhí)行,那么到2執(zhí)行完畢可以將job放入緩沖區(qū),不產(chǎn)生事件消息,等外部操作完成后,創(chuàng)建執(zhí)行事件消息,激發(fā)后續(xù)管道執(zhí)行任務(wù)。(這種方式可以直接利用容器的掛起,來(lái)釋放容器線程,而后續(xù)操作交由后臺(tái)業(yè)務(wù)線程池執(zhí)行)

    這里有點(diǎn)說(shuō)明一下,也是很多朋友問(wèn)起的,關(guān)于上下文,原來(lái)的模式中上下文一種方式是通過(guò)方法參數(shù)不斷傳遞,另一種方式保存在ThreadLocal中,而現(xiàn)在因?yàn)橐袚Q線程可能就需要做拷貝或者線程之間傳遞。在后面幾種模式中都建議直接將狀態(tài)存儲(chǔ)在本地緩存中共享,帶來(lái)的問(wèn)題就是多線程安全,一種方式是都獲取此對(duì)象,然后操作時(shí)候做鎖,一種是獲得對(duì)象快照,然后合并結(jié)果時(shí)鎖定。(這還是取決于多個(gè)線程之間處理是否需要看到對(duì)方的數(shù)據(jù)變化)

                                                     

             34兩個(gè)任務(wù)可以并行完成,同時(shí)任何一個(gè)完成即可進(jìn)入5,此時(shí)在2完成后,將會(huì)產(chǎn)生兩個(gè)執(zhí)行任務(wù)消息,并且自描述后續(xù)的Pipe,此時(shí)兩個(gè)線程可以分別執(zhí)行34,任何一個(gè)完畢后創(chuàng)建執(zhí)行消息,激發(fā)任務(wù)處理進(jìn)入到5流程中。(當(dāng)發(fā)現(xiàn)已經(jīng)進(jìn)入5狀態(tài)時(shí),則忽略某個(gè)過(guò)期任務(wù)消息)

                                                       

             與上一個(gè)圖的區(qū)別就是,34將不再是二選一,而是必須全執(zhí)行完畢后才可以進(jìn)入下一個(gè)階段,因此job在執(zhí)行后會(huì)先判斷是否被并行的另一個(gè)任務(wù)執(zhí)行過(guò),確定全部都Ready,則發(fā)起創(chuàng)建執(zhí)行消息。(在完成3或者4后都會(huì)判斷當(dāng)前合并結(jié)果是否符合進(jìn)入下一環(huán)節(jié)的要求,符合再發(fā)起新的執(zhí)行任務(wù)消息)

                                                   

             此圖是23兩種方案的結(jié)合,因此參照3的做法完成。

    支持異步化請(qǐng)求處理模型:

             上面的管道模型是較為通用的模型,但考慮到TOP現(xiàn)有業(yè)務(wù)狀況和資源消耗在上述框架下定制了簡(jiǎn)單的異步支持模型:

                                                          

    角色及流程說(shuō)明:

             App第三方ISV軟件,Container Web容器,PipeManager管道注冊(cè)管理者(區(qū)別于通用的管道注冊(cè)中心在于他對(duì)于所有請(qǐng)求都只管理一套Pipe Chain,由他將請(qǐng)求數(shù)據(jù)傳入,并管理整個(gè)子任務(wù)的執(zhí)行和分發(fā)),AsynTaskChecker是異步執(zhí)行任務(wù)狀態(tài)變更事件的檢查者(類似于前面的事件分發(fā)器角色),ResultQueue保存事件及事件所帶的上下文,workerThead是工作線程池。

    1. 應(yīng)用發(fā)起服務(wù)請(qǐng)求。

    2. 容器調(diào)用管道管理器去執(zhí)行任務(wù)管道鏈。(解析參數(shù)通過(guò)Lazy方式解析字節(jié)流被離散放到了各個(gè)管道環(huán)節(jié)中)

    3. 檢查容器是否對(duì)異步支持。(便于多容器兼容)

    4. 創(chuàng)建上下文和輸入輸出對(duì)象(輸入輸出是管道基本傳遞參數(shù),后面給出類圖結(jié)構(gòu)可知,上下文則是放置在ThreadLocal的數(shù)據(jù),在多個(gè)管道邏輯中共享)。

    5. 設(shè)置管道鏈執(zhí)行的起始點(diǎn)(為了異步化后再次進(jìn)入管道鏈無(wú)需重新執(zhí)行前面執(zhí)行過(guò)的管道作處理)。

    6. 循環(huán)執(zhí)行管道鏈。

    如有異步管道在管道鏈中:

    a)         復(fù)制管道上下文,保存當(dāng)前執(zhí)行的管道位置。

    b)         掛起請(qǐng)求,釋放容器線程資源。

    c)         創(chuàng)建線程執(zhí)行異步化管道。

    d)         保存任務(wù)到隊(duì)列,等待外部處理結(jié)束改變?nèi)蝿?wù)狀態(tài)。

    e)         推出循環(huán)執(zhí)行后續(xù)管道

    7. 判斷是否是異步執(zhí)行后的重入,如果是則提交異步結(jié)束事件,讓容器在這次管道鏈執(zhí)行后自動(dòng)提交數(shù)據(jù)到客戶端,結(jié)束本地Http請(qǐng)求會(huì)話。

    8. 釋放上下文等線程本地資源。

    9. 返回容器,容器判斷是否有掛起請(qǐng)求,如果請(qǐng)求結(jié)束則返回結(jié)果到客戶端。

    10.              容器自檢查從掛起到當(dāng)前是否處于執(zhí)行超時(shí)(每次掛起請(qǐng)求就會(huì)產(chǎn)生一個(gè)超時(shí)事件,容器循環(huán)的校驗(yàn)這些事件)

    11.              AsynTaskChecker循環(huán)的檢查隊(duì)列中的任務(wù)是否已經(jīng)完成,如果狀態(tài)變更為完成,則提交到給線程池繼續(xù)執(zhí)行后續(xù)的管道鏈。(處于性能考慮,可以將未完成的對(duì)象先不放入隊(duì)列,等到后端服務(wù)處理完畢再放入,這樣AsynTaskChecker消耗會(huì)大大降低,任務(wù)超時(shí)完全交給容器來(lái)處理,不由業(yè)務(wù)方來(lái)處理

    細(xì)節(jié):

             主要目的是將容器和業(yè)務(wù)線程池分開(kāi),這樣業(yè)務(wù)線程池可以采用后面提到的權(quán)重線程池,通過(guò)對(duì)權(quán)重線程池的權(quán)重模型設(shè)置來(lái)滿足根據(jù)業(yè)務(wù)或者根據(jù)服務(wù)健康狀況來(lái)不均衡的分配線程執(zhí)行不同的業(yè)務(wù)請(qǐng)求。

             后端系統(tǒng)的NIO異步方式能夠利用操作系統(tǒng)的中斷來(lái)激發(fā)改變對(duì)象狀態(tài),節(jié)省前端業(yè)務(wù)線程等待消耗。(如果后端是非異步化的操作,那么執(zhí)行線程只是從容器線程變?yōu)榱藰I(yè)務(wù)線程,當(dāng)然可以讓業(yè)務(wù)線程更加輕量)

             系統(tǒng)中盡量減少線程切換(能夠一個(gè)線程干完的,盡量一個(gè)線程執(zhí)行多個(gè)子任務(wù)),盡量減少內(nèi)存拷貝復(fù)用對(duì)象(當(dāng)然復(fù)用的代價(jià)就是同步問(wèn)題,因此取決于數(shù)據(jù)操作沖突的概率選擇使用快照還是引用)。


                                                    

             上圖的設(shè)計(jì)省略了隊(duì)列和檢查者,直接交由業(yè)務(wù)線程阻塞方式等待返回,并直接執(zhí)行后續(xù)的管道,其實(shí)也就是對(duì)第一種場(chǎng)景的簡(jiǎn)化,在后端服務(wù)非異步方式的情況下,推薦這種方式。

    總的來(lái)說(shuō),任務(wù)切割執(zhí)行在設(shè)計(jì)上會(huì)覺(jué)得很清晰,但是還是要看整體處理時(shí)間的分布,如果整個(gè)事務(wù)處理消耗的時(shí)間很短,那么切割帶來(lái)的復(fù)雜度和內(nèi)部消耗就會(huì)得不償失,采用簡(jiǎn)單的方式來(lái)實(shí)現(xiàn)可以滿足業(yè)務(wù)上的需求(分離容器和業(yè)務(wù)線程,根據(jù)業(yè)務(wù)需求和系統(tǒng)動(dòng)態(tài)性能決定線程資源分配),也能保證性能。

    權(quán)重線程池:

             將請(qǐng)求全程處理從容器線程池分離到業(yè)務(wù)線程池后,可以使用帶權(quán)重的線程池來(lái)動(dòng)態(tài)調(diào)整請(qǐng)求線程資源分配,下面是一個(gè)簡(jiǎn)單的權(quán)重線程池的實(shí)現(xiàn)。

    目標(biāo):執(zhí)行的任務(wù)實(shí)現(xiàn)接口getkey來(lái)用于判斷是否有空余線程可以執(zhí)行請(qǐng)求處理任務(wù)。資源被分成兩種:默認(rèn)全局可使用資源,給特定請(qǐng)求預(yù)留資源。配置分成兩種,限制最大使用線程數(shù),預(yù)留特定請(qǐng)求的線程數(shù)。

                                                    

             上圖是簡(jiǎn)單的請(qǐng)求任務(wù)執(zhí)行流程圖,不多解釋了。下圖是狀態(tài)轉(zhuǎn)換圖:

                                                    

             Waitdoing的轉(zhuǎn)換和initdoing的轉(zhuǎn)換一樣,就沒(méi)有重復(fù)畫(huà)了。內(nèi)部的一些標(biāo)識(shí)解釋(totalCounter全局的計(jì)數(shù)器,maxThreadPoolSize線程池最大線程數(shù),defaultCounter是沒(méi)有設(shè)置預(yù)留或者限制的請(qǐng)求的計(jì)數(shù)器,defaultThresholdmaxThreadPoolSize – sum(預(yù)留線程)keyCounter表示設(shè)置了預(yù)留或者限制的請(qǐng)求自身標(biāo)識(shí)(自身標(biāo)識(shí)通過(guò)getkey接口獲得)計(jì)數(shù)器,leave表示某一類請(qǐng)求設(shè)置的預(yù)留的數(shù)值,limit表示某一類請(qǐng)求設(shè)置的限制的數(shù)值)

    上圖中大括號(hào)中的是場(chǎng)景描述,例如:{Limit Mode}keyCounter <= limit && defaultCounter <= defaultThreshold表示在設(shè)置了限制模式的場(chǎng)景下符合當(dāng)前請(qǐng)求類型計(jì)數(shù)器(當(dāng)前請(qǐng)求類型通過(guò)請(qǐng)求實(shí)現(xiàn)getkey接口返回?cái)?shù)據(jù)來(lái)區(qū)別)小于限制且默認(rèn)計(jì)數(shù)器小于默認(rèn)閥值時(shí)狀態(tài)轉(zhuǎn)變。

    一點(diǎn)小技巧:在存儲(chǔ)預(yù)留和限制的閥值時(shí),因?yàn)榇鎯?chǔ)在一個(gè)map中,通過(guò)將閥值設(shè)置為負(fù)數(shù)來(lái)區(qū)分開(kāi),這樣節(jié)省了區(qū)分閥值類型的工作。(這點(diǎn)可以在很多場(chǎng)景中考慮,比如說(shuō)有多個(gè)類型的數(shù)據(jù)配置需要存儲(chǔ),可以通過(guò)數(shù)據(jù)區(qū)間的劃分來(lái)判斷是什么類型的,提高判斷效率)

    Comet Push Framework:

             服務(wù)端實(shí)現(xiàn):這期做了很簡(jiǎn)單的服務(wù)端實(shí)現(xiàn),也是為了驗(yàn)證原型,標(biāo)準(zhǔn)的REST實(shí)現(xiàn)。

                                                    

             POST操作,用于新增資源,操作后得到資源返回,會(huì)話非長(zhǎng)連接。


                                                          

             GET操作,獲得當(dāng)前請(qǐng)求的資源,會(huì)被加入到資源關(guān)注者列表中,保持長(zhǎng)連接,用于資源變更后推送變更后的資源對(duì)象。

                                                       

             PUT或者Delete操作,短鏈接,同時(shí)產(chǎn)生變化事件,交由后臺(tái)線程執(zhí)行通知?jiǎng)幼鳌?br />
                                                        

             批量執(zhí)行通知消息。

    1. ResourceBoard阻塞式的從隊(duì)列中獲取事件通知。

    2. 創(chuàng)建臨時(shí)事件存儲(chǔ)Map

    3. 如果存在通知事件,判斷是否屬于刪除事件(此類事件發(fā)生在異常發(fā)生或者正常結(jié)束),如果是刪除事件,立刻提交給后臺(tái)線程池執(zhí)行刪除動(dòng)作。(刪除動(dòng)作就是獲取刪除資源的follow列表,然后關(guān)閉所有follow的長(zhǎng)連接)

    4. 如果屬于修改事件,判斷當(dāng)前資源的刪除事件是否已經(jīng)保存在臨時(shí)存儲(chǔ)Map中,如果有就不再加入修改事件直接忽略,否則就放入Map

    5. 判斷當(dāng)前循環(huán)累積事件是否超過(guò)一定時(shí)間或者存儲(chǔ)的消息量已經(jīng)超過(guò)一定值,如果是就跳出循環(huán),如果否,則繼續(xù)從隊(duì)列中獲取數(shù)據(jù)循環(huán)判斷,直到隊(duì)列為空。

    6. 批量執(zhí)行臨時(shí)存儲(chǔ)中的事件消息,如果是修改,則獲取資源的follows來(lái)推送變更后的數(shù)據(jù)。

    細(xì)節(jié):

        內(nèi)部對(duì)于follow的有效性管理是在發(fā)送數(shù)據(jù)時(shí)判斷的,如果出錯(cuò)就會(huì)產(chǎn)生刪除事件。

    對(duì)于消息批量處理主要是針對(duì)數(shù)據(jù)不斷被修改,合并這些無(wú)用消息而作,但是某些場(chǎng)景也許就需要所有的修改痕跡,那就不能簡(jiǎn)單合并,因此資源需要提供類似合并的接口實(shí)現(xiàn)來(lái)保證獲取的正確性。

             問(wèn)題:

           海量長(zhǎng)連接的支持。

           采用簡(jiǎn)單的Http InnerFrame + js實(shí)現(xiàn)客戶端增量展現(xiàn)會(huì)使得頁(yè)面數(shù)據(jù)越來(lái)越多,到一定程度需要放棄連接重新建立follow,減輕客戶端和服務(wù)端雙重壓力。XHR的方式在各種瀏覽器中支持的不一致。


         代碼實(shí)現(xiàn),
    Demo及測(cè)試效果

    待續(xù)….

    posted on 2010-11-25 14:44 岑文初 閱讀(4116) 評(píng)論(7)  編輯  收藏

    評(píng)論

    # re: 基于管道化和事件驅(qū)動(dòng)模型的Web請(qǐng)求處理(二) 2010-11-25 15:11 BucketLI
    我主要有3個(gè)問(wèn)題
    1.并行任務(wù)執(zhí)行的線程池是自己實(shí)現(xiàn)的還是使用Concurrent包的線程池?然后線程池的飽和拒絕策略采用的是什么策略?因?yàn)镃oncurrent包中的線程池如果不擴(kuò)展沒(méi)有如同數(shù)據(jù)庫(kù)連接池的等待超時(shí)策略,一旦滿了就立刻執(zhí)行飽和拒絕策略里面的行為,所以你實(shí)現(xiàn)的線程池(如果是的話)飽和拒絕策略是否加入了超時(shí)特性,或者干脆使用主線程執(zhí)行?

    2.并行執(zhí)行任務(wù)結(jié)果需要同步合并的場(chǎng)景中,如果其中某個(gè)并行任務(wù)失敗,是強(qiáng)行取消其他正常任務(wù),并且回收資源,還是讓其執(zhí)行完畢?

    3.另外通過(guò)不斷輪詢隊(duì)列中的任務(wù)是否完成與通過(guò)CountDownLatch的通知,哪種會(huì)比較強(qiáng)?至少后者我需要維護(hù)閉鎖在異常情景下的行為,否則會(huì)導(dǎo)致內(nèi)存泄露,感覺(jué)比較復(fù)雜(這是我們一個(gè)場(chǎng)景實(shí)現(xiàn)的方式).  回復(fù)  更多評(píng)論
      

    # re: 基于管道化和事件驅(qū)動(dòng)模型的Web請(qǐng)求處理(二) 2010-11-25 20:04 岑文初
    @BucketLI
    1.有權(quán)重的的線程池是基于concurrent上封裝的,自己嘗試過(guò)封裝,性能差不多,就沒(méi)什么意思了,現(xiàn)在配置maxpoolsize和minpoolsize是一樣大的,這樣當(dāng)線程池到了上限后就放入隊(duì)列,隊(duì)列滿了就丟棄,如果需要加入超時(shí)特性,其實(shí)就把線程池自帶的隊(duì)列中的數(shù)據(jù)封裝帶有時(shí)間戳,然后定時(shí)輪詢清理掉過(guò)期任務(wù)。或者采用時(shí)間槽的概念,比如分成6個(gè)時(shí)間槽,每隔10分鐘切換一個(gè)時(shí)間槽,那么當(dāng)你任務(wù)20分鐘是容忍極限的話,那么在每次切換時(shí)間槽的時(shí)候清除相隔2個(gè)位置的隊(duì)列。
    2.這個(gè)還是看你自己的策略,簡(jiǎn)單來(lái)說(shuō),如果一個(gè)必選步驟錯(cuò)了,就產(chǎn)生結(jié)束任務(wù)的事件,有后臺(tái)線程執(zhí)行刪除任務(wù)操作。
    3.CountDownLatch你是用線程阻塞?為每一個(gè)任務(wù)都分配一個(gè)?我不是很清楚你的做法,但是個(gè)人感覺(jué)CountDownLatch用于任務(wù)的join啟動(dòng)和結(jié)束比較好,你也可以描述一下你們的做法?  回復(fù)  更多評(píng)論
      

    # re: 基于管道化和事件驅(qū)動(dòng)模型的Web請(qǐng)求處理(二) 2010-11-26 09:41 BucketLI
    @岑文初
    1.這個(gè)問(wèn)題主要在壓力測(cè)試的時(shí)候發(fā)現(xiàn)的,比如并行的任務(wù)線程池大小為10,隊(duì)列為20,也就是同時(shí)能夠提交的任務(wù)最大30個(gè),后面SUBMIT或者EXECUTE被拒絕(直接拒絕策略),這確實(shí)是符合要求的,但有一個(gè)問(wèn)題是,假設(shè)一次請(qǐng)求生成5個(gè)左右的并行任務(wù),只要其中一個(gè)任務(wù)失敗就這次請(qǐng)求失敗,因?yàn)榫€程池一直處于忙碌狀態(tài),所以這5個(gè)任務(wù)很有可能被部分拒絕,實(shí)際上是數(shù)量>=2的并行任務(wù)都有可能被部分拒絕導(dǎo)致這次請(qǐng)求失敗. 所以我的策略改成主線程來(lái)執(zhí)行了,但我認(rèn)為有個(gè)等待超時(shí)會(huì)更好.

    3.因?yàn)橹骶€程得收集到并行任務(wù)執(zhí)行完畢的所有結(jié)果才能進(jìn)行下一步操作(也就是屏障),有N個(gè)并行任務(wù),我就實(shí)現(xiàn)一個(gè)CountDown N次的閉鎖,然后主線程提交完任務(wù)后await,任務(wù)持有這個(gè)閉鎖,執(zhí)行完任務(wù)就 CountDown一下,直到CountDown完畢.異常處理是線程池任務(wù)持有主線程實(shí)例,發(fā)生異常的時(shí)候interrupt主線程,主線程響應(yīng)這個(gè)中斷異常,cancel其他任務(wù)以及清理資源.  回復(fù)  更多評(píng)論
      

    # re: 基于管道化和事件驅(qū)動(dòng)模型的Web請(qǐng)求處理(二) 2010-11-26 18:33 anderslin
    后端異步執(zhí)行部分感覺(jué)太麻煩了,不知道是否有考慮過(guò)采用spring batch作為后端執(zhí)行方案?  回復(fù)  更多評(píng)論
      

    # re: 基于管道化和事件驅(qū)動(dòng)模型的Web請(qǐng)求處理(二) 2010-11-29 19:09 單飛
    有點(diǎn)像工作流,干嗎不用jbpm解決流程呢?  回復(fù)  更多評(píng)論
      

    # re: 基于管道化和事件驅(qū)動(dòng)模型的Web請(qǐng)求處理(二) 2010-12-01 09:55 darren
    請(qǐng)問(wèn)你的sequence圖,用那個(gè)uml工具畫(huà)的,rose沒(méi)法畫(huà)循環(huán),你的可以。  回復(fù)  更多評(píng)論
      

    # re: 基于管道化和事件驅(qū)動(dòng)模型的Web請(qǐng)求處理(二) 2010-12-01 21:00 岑文初
    EA@darren
      回復(fù)  更多評(píng)論
      


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


    網(wǎng)站導(dǎo)航:
     
    主站蜘蛛池模板: 永久免费av无码网站yy| 亚洲色欲一区二区三区在线观看| 色吊丝性永久免费看码 | 久久er国产精品免费观看2| 亚洲综合激情五月丁香六月| 亚洲AV人无码激艳猛片| 亚洲精品视频在线看| 99久久免费精品国产72精品九九| 久久狠狠躁免费观看2020| 国产JIZZ中国JIZZ免费看| 色偷偷亚洲第一综合| 亚洲伊人久久大香线蕉结合| 亚洲AV无码专区电影在线观看 | 99视频精品全部免费观看| 狠狠躁狠狠爱免费视频无码| 自拍偷自拍亚洲精品偷一| 特黄aa级毛片免费视频播放| 亚洲国产精品99久久久久久| 2020年亚洲天天爽天天噜| 国产亚洲精aa在线看| 亚洲一级视频在线观看| 亚洲宅男永久在线| 亚洲精品~无码抽插| 国产亚洲色婷婷久久99精品91| 国产yw855.c免费视频| 天天看片天天爽_免费播放| 9久9久女女免费精品视频在线观看| 久久w5ww成w人免费| 99在线视频免费| 成视频年人黄网站免费视频| 性做久久久久免费看| 卡一卡二卡三在线入口免费| 免费一级特黄特色大片在线 | 日韩电影免费在线观看中文字幕| 最近免费视频中文字幕大全| 在线播放高清国语自产拍免费| 亚洲A∨精品一区二区三区| 亚洲成av人片在线观看天堂无码 | 最近最新高清免费中文字幕 | 美女黄色免费网站| 久久精品一区二区免费看|