J2ee高并发情况下监听器

来源:互联网 发布:爱淘宝精品推荐 编辑:程序博客网 时间:2024/05/29 14:44

引言:在高并发下限制最大并发次数,在web.xml中用过滤器设置参数(最大并发数),并设置其他相关参数。详细见代码。

第一步:配置web.xml配置,不懂的地方解释一下:参数50通过参数名maxConcurrent用在filter的实现类中获取,filter-class就是写的实现类,

url-pattern就是限制并发时间的url,结束!



[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <filter>  
  2.     <filter-name>ConcurrentCountFilter</filter-name>  
  3.     <filter-class>com.procure.pass.ConcurrentCountFilter</filter-class>  
  4.     <init-param>  
  5.         <param-name>maxConcurrent</param-name>  
  6.         <param-value>50</param-value>  
  7.     </init-param>  
  8.   </filter>  
  9.   <filter-mapping>  
  10.     <filter-name>ConcurrentCountFilter</filter-name>  
  11.     <url-pattern>/a/pass/export</url-pattern>  
  12.   </filter-mapping>  


第二步:写实现类实现filter,该接口有三个方法,详见代码。




[java] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. import java.io.IOException;  
  2. import java.util.concurrent.atomic.AtomicInteger;  
  3. import javax.servlet.Filter;  
  4. import javax.servlet.FilterChain;  
  5. import javax.servlet.FilterConfig;  
  6. import javax.servlet.ServletException;  
  7. import javax.servlet.ServletRequest;  
  8. import javax.servlet.ServletResponse;  
  9. import javax.servlet.http.HttpServletResponse;  
  10. import org.slf4j.Logger;  
  11. import org.slf4j.LoggerFactory;  
  12.   
  13. /** 
  14.  * Servlet Filter implementation class ConcurrentCountFilter 
  15.  */  
  16. public class ConcurrentCountFilter implements Filter {  
  17.     private static Logger log = LoggerFactory.getLogger(ConcurrentCountFilter.class);  
  18.     private FilterConfig filterConfig;  
  19.     private int maxConcurrent = -1;  
  20.     //总计数  
  21.     private static AtomicInteger count = new AtomicInteger(0);  
  22.       
  23.     /** 
  24.      * 获取当前并发数 
  25.      * @return 
  26.      */  
  27.     public static int get(){    
  28.             return count.get();    
  29.         }   
  30.     /** 
  31.      * 增加并发数量 
  32.      * @return 
  33.      */  
  34.      public static int increase(){    
  35.             return count.incrementAndGet();    
  36.         }  
  37.      /** 
  38.       * 减少并发数量 
  39.       * @return 
  40.       */  
  41.      public static int decrement(){  
  42.          return count.decrementAndGet();  
  43.      }  
  44.       
  45.        
  46.     /** 
  47.      * 初始化 
  48.      */  
  49.         public void init(FilterConfig filterConfig) throws ServletException {  
  50.             //获取配置的最大并发数量  
  51.             String maxStr = filterConfig.getInitParameter("maxConcurrent");  
  52.             int num = -1;  
  53.             if(maxStr != null && !"".equals(maxStr)){  
  54.                 num = Integer.parseInt(maxStr);  
  55.             }  
  56.             if(num >= 1){  
  57.                 this.maxConcurrent = num;  
  58.             }else{  
  59.                 this.maxConcurrent = -1;  
  60.             }  
  61.         }  
  62.         /** 
  63.          * 过滤主方法 
  64.          */  
  65.         public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {  
  66.             try{  
  67.             //增加并发数量  
  68.             int num = increase();  
  69.             if(maxConcurrent > 0){  
  70.                 if(maxConcurrent >= num){  
  71.                     chain.doFilter(request, response);  
  72.                     log.info("第一次并发数量:"+count.get());  
  73.                 }else{  
  74.                     HttpServletResponse res = (HttpServletResponse) response;  
  75.                     res.sendError(HttpServletResponse.SC_SERVICE_UNAVAILABLE,"达到最大并发数限制");  
  76.                     log.info("达到最大并发数");  
  77.                     log.info("最大并发数量:"+count.get());  
  78.                 }  
  79.             }else{  
  80.                 chain.doFilter(request, response);  
  81.                 log.info("第二次并发数量:"+count.get());  
  82.             }  
  83.             }finally {  
  84.                 decrement();  
  85.                 log.info("减小的并发量:"+count.get());  
  86.             }  
  87.           
  88.         }  
  89.     /** 
  90.      * 退出销毁 
  91.      */  
  92.     public void destroy() {  
  93.         this.filterConfig = null;  
  94.         log.info("销毁......");  
  95.     }  
  96. }  

代码到此完。

吐槽一下自己在项目中遇到的坑:

1.response.sendError( int, string);在本文代码中为res.sendError其中若直接如本文代码那样会返回一个503服务器带出来的页面,此页面粗暴及其难看,

在此为了友好通知用户,需做如下步骤,在web.xml中做如下配置代码:


[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <error-page>  
  2.     <error-code>503</error-code>  
  3.     <location>/WEB-INF/views/error/503.jsp</location>  
  4.   </error-page>  

如果在web.xml中配置了上面信息,首先会过滤503(HttpServletResponse.SC_SERVICE_UNAVAILABLE)状态码下的此页面而不会抛服务器的页面。

其中503.jsp页面需自己完成在此仅仅贴出来一个示例做参考,代码如下:

[html] view plain copy
 在CODE上查看代码片派生到我的代码片
  1. <%  
  2. response.setStatus(503);  
  3.   
  4. // 获取异常类  
  5. Throwable ex = Exceptions.getThrowable(request);  
  6. if (ex != null){  
  7.     LoggerFactory.getLogger("500.jsp").error(ex.getMessage(), ex);  
  8. }  
  9.   
  10. // 编译错误信息  
  11. StringBuilder sb = new StringBuilder("错误信息:\n");  
  12. if (ex != null) {  
  13.     sb.append(Exceptions.getStackTraceAsString(ex));  
  14. } else {  
  15.     sb.append("未知错误.\n\n");  
  16. }  
  17.   
  18. // 如果是异步请求或是手机端,则直接返回信息  
  19. if (Servlets.isAjaxRequest(request)) {  
  20.     out.print(sb);  
  21. }  
  22.   
  23. // 输出异常信息页面  
  24. else {  
  25. %>  
  26. <%@page import="org.slf4j.Logger,org.slf4j.LoggerFactory"%>  
  27. <%@page import="com.xahl_oa.internal.common.web.Servlets"%>  
  28. <%@page import="com.xahl_oa.internal.common.utils.Exceptions"%>  
  29. <%@page import="com.xahl_oa.internal.common.utils.StringUtils"%>  
  30. <%@page contentType="text/html;charset=UTF-8" isErrorPage="true"%>  
  31. <%@include file="/WEB-INF/views/include/taglib.jsp"%>  
  32. <!DOCTYPE html>  
  33. <html>  
  34. <head>  
  35.     <title>503 - 服务暂时不可用</title>  
  36.     <%@include file="/WEB-INF/views/include/head.jsp" %>  
  37. </head>  
  38. <body>  
  39.     <div class="container-fluid">  
  40.         <div class="page-header"><h1>服务暂时不可用请稍后再试.</h1></div>  
  41.         <div class="errorMessage">  
  42.             错误信息:<%=ex==null?"未知错误.":StringUtils.toHtml(ex.getMessage())%> <br/> <br/>  
  43.             服务器暂时不可用请稍后再试,谢谢!<br/> <br/>  
  44.             <a href="javascript:" onclick="history.go(-1);" class="btn">返回上一页</a>    
  45.             <a href="javascript:" onclick="$('.errorMessage').toggle();" class="btn">查看详细信息</a>  
  46.         </div>  
  47.         <div class="errorMessage hide">  
  48.             <%=StringUtils.toHtml(sb.toString())%> <br/>  
  49.             <a href="javascript:" onclick="history.go(-1);" class="btn">返回上一页</a>    
  50.             <a href="javascript:" onclick="$('.errorMessage').toggle();" class="btn">隐藏详细信息</a>  
  51.             <br/> <br/>  
  52.         </div>  
  53.         <script>try{top.$.jBox.closeTip();}catch(e){}</script>  
  54.     </div>  
  55. </body>  
  56. </html>  
  57. <%  
  58. out = pageContext.pushBody();  
  59. %>  


此页面就比服务器抛出的页面友好甚多。

0 0
原创粉丝点击