J2ee 高并发情况下监听器实例详解
程序员文章站
2024-03-06 13:46:38
j2ee 高并发情况下监听器实例详解
引言:在高并发下限制最大并发次数,在web.xml中用过滤器设置参数(最大并发数),并设置其他相关参数。详细见代码。
第一步:配置...
j2ee 高并发情况下监听器实例详解
引言:在高并发下限制最大并发次数,在web.xml中用过滤器设置参数(最大并发数),并设置其他相关参数。详细见代码。
第一步:配置web.xml配置,不懂的地方解释一下:参数50通过参数名maxconcurrent用在filter的实现类中获取,filter-class就是写的实现类,
url-pattern就是限制并发时间的url,结束!
<filter> <filter-name>concurrentcountfilter</filter-name> <filter-class>com.procure.pass.concurrentcountfilter</filter-class> <init-param> <param-name>maxconcurrent</param-name> <param-value>50</param-value> </init-param> </filter> <filter-mapping> <filter-name>concurrentcountfilter</filter-name> <url-pattern>/a/pass/export</url-pattern> </filter-mapping>
第二步:写实现类实现filter,该接口有三个方法,详见代码。
import java.io.ioexception; import java.util.concurrent.atomic.atomicinteger; import javax.servlet.filter; import javax.servlet.filterchain; import javax.servlet.filterconfig; import javax.servlet.servletexception; import javax.servlet.servletrequest; import javax.servlet.servletresponse; import javax.servlet.http.httpservletresponse; import org.slf4j.logger; import org.slf4j.loggerfactory; /** * servlet filter implementation class concurrentcountfilter */ public class concurrentcountfilter implements filter { private static logger log = loggerfactory.getlogger(concurrentcountfilter.class); private filterconfig filterconfig; private int maxconcurrent = -1; //总计数 private static atomicinteger count = new atomicinteger(0); /** * 获取当前并发数 * @return */ public static int get(){ return count.get(); } /** * 增加并发数量 * @return */ public static int increase(){ return count.incrementandget(); } /** * 减少并发数量 * @return */ public static int decrement(){ return count.decrementandget(); } /** * 初始化 */ public void init(filterconfig filterconfig) throws servletexception { //获取配置的最大并发数量 string maxstr = filterconfig.getinitparameter("maxconcurrent"); int num = -1; if(maxstr != null && !"".equals(maxstr)){ num = integer.parseint(maxstr); } if(num >= 1){ this.maxconcurrent = num; }else{ this.maxconcurrent = -1; } } /** * 过滤主方法 */ public void dofilter(servletrequest request, servletresponse response, filterchain chain) throws ioexception, servletexception { try{ //增加并发数量 int num = increase(); if(maxconcurrent > 0){ if(maxconcurrent >= num){ chain.dofilter(request, response); log.info("第一次并发数量:"+count.get()); }else{ httpservletresponse res = (httpservletresponse) response; res.senderror(httpservletresponse.sc_service_unavailable,"达到最大并发数限制"); log.info("达到最大并发数"); log.info("最大并发数量:"+count.get()); } }else{ chain.dofilter(request, response); log.info("第二次并发数量:"+count.get()); } }finally { decrement(); log.info("减小的并发量:"+count.get()); } } /** * 退出销毁 */ public void destroy() { this.filterconfig = null; log.info("销毁......"); } }
代码到此完。
吐槽一下自己在项目中遇到的坑:
1.response.senderror( int, string);在本文代码中为res.senderror其中若直接如本文代码那样会返回一个503服务器带出来的页面,此页面粗暴及其难看,
在此为了友好通知用户,需做如下步骤,在web.xml中做如下配置代码:
<error-page> <error-code>503</error-code> <location>/web-inf/views/error/503.jsp</location> </error-page>
如果在web.xml中配置了上面信息,首先会过滤503(httpservletresponse.sc_service_unavailable)状态码下的此页面而不会抛服务器的页面。
其中503.jsp页面需自己完成在此仅仅贴出来一个示例做参考,代码如下:
<% response.setstatus(503); // 获取异常类 throwable ex = exceptions.getthrowable(request); if (ex != null){ loggerfactory.getlogger("500.jsp").error(ex.getmessage(), ex); } // 编译错误信息 stringbuilder sb = new stringbuilder("错误信息:\n"); if (ex != null) { sb.append(exceptions.getstacktraceasstring(ex)); } else { sb.append("未知错误.\n\n"); } // 如果是异步请求或是手机端,则直接返回信息 if (servlets.isajaxrequest(request)) { out.print(sb); } // 输出异常信息页面 else { %> <%@page import="org.slf4j.logger,org.slf4j.loggerfactory"%> <%@page import="com.xahl_oa.internal.common.web.servlets"%> <%@page import="com.xahl_oa.internal.common.utils.exceptions"%> <%@page import="com.xahl_oa.internal.common.utils.stringutils"%> <%@page contenttype="text/html;charset=utf-8" iserrorpage="true"%> <%@include file="/web-inf/views/include/taglib.jsp"%> <!doctype html> <html> <head> <title>503 - 服务暂时不可用</title> <%@include file="/web-inf/views/include/head.jsp" %> </head> <body> <div class="container-fluid"> <div class="page-header"><h1>服务暂时不可用请稍后再试.</h1></div> <div class="errormessage"> 错误信息:<%=ex==null?"未知错误.":stringutils.tohtml(ex.getmessage())%> <br/> <br/> 服务器暂时不可用请稍后再试,谢谢!<br/> <br/> <a href="javascript:" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" onclick="history.go(-1);" class="btn">返回上一页</a> <a href="javascript:" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" onclick="$('.errormessage').toggle();" class="btn">查看详细信息</a> </div> <div class="errormessage hide"> <%=stringutils.tohtml(sb.tostring())%> <br/> <a href="javascript:" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" onclick="history.go(-1);" class="btn">返回上一页</a> <a href="javascript:" rel="external nofollow" rel="external nofollow" rel="external nofollow" rel="external nofollow" onclick="$('.errormessage').toggle();" class="btn">隐藏详细信息</a> <br/> <br/> </div> <script>try{top.$.jbox.closetip();}catch(e){}</script> </div> </body> </html> <% } out = pagecontext.pushbody(); %>
此页面就比服务器抛出的页面友好甚多。
感谢阅读,希望能帮助到大家,谢谢大家对本站的支持!