在企业级的应用中,经常会存在一些访问非常频繁的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