在企業級的應用中,經常會存在一些訪問非常頻繁的web應用,這些web模塊很容易就會將GlassFish的HTTP
Thread全部占滿,這時其它的web應用就始終在queue中等待獲取HTTP的connection,直至超時。
在Weblogic中,我們可以通過在weblogic.xml中設置wl-dispatch-policy去引用創建的execute queue,來控制該web應用可使用的線程數。但在GlassFish中就沒有相應的實現方式,如果是EJB組件,可以采取Request Partitioning的方式來分配模塊所使用的資源,可參考http://docs.sun.com/app/docs/doc/820-4343/abecu?a=view。對于Web應用只有等到V3版本發布時才具備資源分配的功能了,查看GlassFish
V3 Improvement List: http://wiki.glassfish.java.net/Wiki.jsp?page=V3GeneralImprovements,
其中的Gen-009就是對應的這項功能。對于SUN現在的局面,不知道要等到什么時候才會發布這個feature,好在已從SUN離職的Grizzly的開發者Jeanfrancois在V2中就已經實現了該功能,可以通過配置的方式實現web資源的分配。
Grizzly的Application Resources
Allocation(ARA)擴展是GlassFish的Resource Consumption
Management(RCM)的web實現。ARA允許你為每個web應用虛擬化系統資源,就像Solaris
10 中的Zone。ARA現在支持兩種應用于TCP請求的規則:
1.
保留指定比率的可用的heap
memory;
2.
保留指定比率的可用的thread;
對于我當前的場景,只需要使用第二種規則即可。要實現這種資源分配的配置,需要加入以下的配置:
1.
在http-listener-1中添加property:rcmSupport=true;
2.
添加jvm-options:-Dcom.sun.enterprise.web.ara.policyMetric=/yourApp/requestURI1|0.5,/yourApp/requestURI2|0.3;
通過上面的配置,Grizzly將會保留50%的線程為/yourApp/requestURI1的請求處理,30%用于/yourApp/requestURI2的處理,剩余的20%用于其它請求的處理。總的線程數為http-service.request-processing.thread-count減去http-service.request-processing.initial-thread-count,initial-thread-count創建出來的那幾個線程好像就沒用了,但是該值不能設為0,至少要為1。
本以為到此就算結束了,但GlassFish實在是太偷工減料了,默認實現的ThreadRatioRule匹配不到我設置的URL,并且創建線程的函數不是線程安全的,當有并發請求進來的時候,就會創建很多組線程,無奈之下只有自己重新寫了個實現,最后把實現類打了個jar,然后在java-config的classpath-prefix指定該jar。最后檢查一下你的http-listener-1中是否有proxiedProtocols屬性,如果有的話就必須要刪除,否則RCM不生效,該屬性在developer模式中不存在,在Cluster模式下默認會添加。
現在你的Web應用就可以實現資源分配了,如果Grizzly默認的實現不滿足你的要求,還可以擴展他的實現。
參考資料:
Resource
Consumption Management using GlassFish
Improving
Ajax performance and usability by using request based priority