在企業級的應用中,經常會存在一些訪問非常頻繁的web應用,這些web模塊很容易就會將GlassFishHTTP Thread全部占滿,這時其它的web應用就始終在queue中等待獲取HTTPconnection,直至超時。
   在
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的開發者JeanfrancoisV2中就已經實現了該功能,可以通過配置的方式實現web資源的分配。
      GrizzlyApplication Resources Allocation(ARA)擴展是GlassFishResource Consumption Management(RCM)web實現。ARA允許你為每個web應用虛擬化系統資源,就像Solaris 10 中的ZoneARA現在支持兩種應用于TCP請求的規則:

1.      保留指定比率的可用的heap memory

2.      保留指定比率的可用的thread

對于我當前的場景,只需要使用第二種規則即可。要實現這種資源分配的配置,需要加入以下的配置:

1.      http-listener-1中添加propertyrcmSupport=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-countinitial-thread-count創建出來的那幾個線程好像就沒用了,但是該值不能設為0,至少要為1
   本以為到此就算結束了,但
GlassFish實在是太偷工減料了,默認實現的ThreadRatioRule匹配不到我設置的URL,并且創建線程的函數不是線程安全的,當有并發請求進來的時候,就會創建很多組線程,無奈之下只有自己重新寫了個實現,最后把實現類打了個jar,然后在java-configclasspath-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