引言:在高并发下限制最大并发次数,在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当中若直接如本文代码那样会返回一个503server带出来的页面,此页面粗暴及其难看。

在此为了友好通知用户,需做例如以下步骤。在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)状态码下的此页面而不会抛server的页面。

当中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/>
server临时不可用请稍后再试,谢谢。<br/> <br/>
<a href="javascript:" onclick="history.go(-1);" class="btn">返回上一页</a>  
<a href="javascript:" onclick="$('.errorMessage').toggle();" class="btn">查看具体信息</a>
</div>
<div class="errorMessage hide">
<%=StringUtils.toHtml(sb.toString())%> <br/>
<a href="javascript:" onclick="history.go(-1);" class="btn">返回上一页</a>  
<a href="javascript:" onclick="$('.errorMessage').toggle();" class="btn">隐藏具体信息</a>
<br/> <br/>
</div>
<script>try{top.$.jBox.closeTip();}catch(e){}</script>
</div>
</body>
</html>
<%
} out = pageContext.pushBody();
%>

此页面就比server抛出的页面友好甚多。

本文借鉴自:http://blog.csdn.net/zyb134506/article/details/41692893   在此谢谢此篇博客。

J2ee高并发情况下监听器的更多相关文章

  1. 关于WCF服务在高并发情况下报目标积极拒绝的异常处理

    最近弄了个wcf的监控服务,偶尔监控到目标服务会报一个目标积极拒绝的错误.一开始以为服务停止了,上服务器检查目标服务好好的活着.于是开始查原因. 一般来说目标积极拒绝(TCP 10061)的异常主要是 ...

  2. WCF服务在高并发情况下报目标积极拒绝的异常处理 z

    http://www.cnblogs.com/kklldog/p/5037006.html wcf的监控服务,偶尔监控到目标服务会报一个目标积极拒绝的错误.一开始以为服务停止了,上服务器检查目标服务好 ...

  3. Jackson高并发情况下,产生阻塞

    情况:在高并发情况下,查看线程栈信息,有大量的线程BLOCKED. 从线程栈得知,线程栈中出现了阻塞,锁在了com.fasterxml.jackson.databind.ser.SerializerC ...

  4. Linux的虚拟内存管理-如何分配和释放内存,以提高服务器在高并发情况下的性能,从而降低了系统的负载

    Linux的虚拟内存管理有几个关键概念: Linux 虚拟地址空间如何分布?malloc和free是如何分配和释放内存?如何查看堆内内存的碎片情况?既然堆内内存brk和sbrk不能直接释放,为什么不全 ...

  5. 高并发情况下分布式全局ID

    1.高并发情况下,生成分布式全局id策略2.利用全球唯一UUID生成订单号优缺点3.基于数据库自增或者序列生成订单号4.数据库集群如何考虑数据库自增唯一性5.基于Redis生成生成全局id策略6.Tw ...

  6. c# redis 利用锁(StackExchange.Redis LockTake)来保证数据在高并发情况下的正确性

    之前有写过一篇介绍c#操作redis的文章 http://www.cnblogs.com/axel10/p/8459434.html ,这篇文章中的案例使用了StringIncrement来实现了高并 ...

  7. 小D课堂 - 新版本微服务springcloud+Docker教程_6-05 高级篇幅之高并发情况下

    笔记 5.高级篇幅之高并发情况下接口限流特技         简介:谷歌guava框架介绍,网关限流使用 1.nginx层限流 2.网关层限流 开始 mysql最大的连接数就是3千多.如果想把应用搞好 ...

  8. Java高并发情况下的锁机制优化

    本文主要讲并行优化的几种方式, 其结构如下: 锁优化 减少锁的持有时间 例如避免给整个方法加锁 1 public synchronized void syncMethod(){ 2 othercode ...

  9. Mysql在高并发情况下,防止库存超卖而小于0的解决方案

    背景: 本人上次做申领campaign的PHP后台时,因为项目上线后某些时段同时申领的人过多,导致一些专柜的存货为负数(<0),还好并发量不是特别大,只存在于小部分专柜而且一般都是-1的状况,没 ...

随机推荐

  1. linux学习笔记-12.输入输出重定向及管道

    1.新建一个文件 touch a.txt> b.txt 2.错误重定向:2> find /etc -name zhaoxing.txt 2> error.txt 3.将正确或错误的信 ...

  2. jenkins自动构建部署

    环境 centos7   tomcat8.5.37   maven3.3.9   jdk8   git1.8.3.1 安装jdk,tomcat,maven,git(环境变量,配置文件什么的自行百度) ...

  3. ubuntu下安装flash player,浏览器观看视频,本人ubuntu版本14.04

    首先去官网下载flash player安装包:flash_player_npapi_linux.x86_64,下载地址:https://get.adobe.com/cn/flashplayer/ 解压 ...

  4. java 生成随机数字

    for(int i=0;i<size1;i++){ int n = (int)(java.lang.Math.random()*99); LinkNode newLink = new LinkN ...

  5. Android-语言国际化

    Android-语言国际化 参考 http://www.loc.gov/standards/iso639-2/php/code_list.php 各国语言表 Overview Internationa ...

  6. hdu 5195 线段树

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAABIgAAABeCAIAAADHZri1AAATWklEQVR4nO3dvU4jTRaA4b2nvgNzBw

  7. 微信小程序自定义音频组件,自定义滚动条,单曲循环,循环播放

    小程序自定义音频组件,带滚动条 摘要:首先自定义音频组件,是因为产品有这样的需求,需要如下样式的 而微信小程序API给我们提供的就是这样的 而且产品需要小程序有后台播放功能,所以我们不考虑小程序的 a ...

  8. consul vs etcd3

    https://sysadmin.libhunt.com/project/etcd/vs/consul

  9. [廖雪峰] Git 分支管理(1):创建与合并分支(HEAD、master、dev、指针)

    每次提交,Git 都把它们串成一条时间线,这条时间线就是一个分支.截止到目前,只有一条时间线,在 Git 里,这个分支叫主分支,即 master 分支.HEAD 严格来说不是指向提交,而是指向 mas ...

  10. 推荐一个文献翻译软件--Deja Vu X

    首先我的这篇博客推荐的软件并非你觉得翻译精确度有多高的软件,假设是这种话就不用往下看了,免得浪费时间,仅仅是一个对于翻译文献非常方便的工具,方面在哪请看下文. 我是不会告诉你凡事用过这个软件的人都说好 ...