引言:在高并发下限制最大并发次数,在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. s3fs挂s3作为本地盘制作ftp使用

    一. 安装s3fs 安装s3fs-fuserhttps://github.com/s3fs-fuse/s3fs-fuse 二. 安装vsftpd #查看当前系统版本cat /etc/redhat-re ...

  2. 在android中实现webview与javascript之间的交互(转)

    参见“在android中实现webview与javascript之间的交互”

  3. 005.iSCSI客户端配置示例-Windows

    一 环境 Linux作为iSCSI服务端,Windows2008R2作为iSCSI客户端 二 服务端配置过程 2.1 客户端配置 在Linux上参照之前的配置建立三个LUN卷作为共享盘,最终配置如下: ...

  4. JAVAEE——SpringBoot日志篇:日志框架SLF4j、日志配置、日志使用、切换日志框架

    Spring Boot 日志篇 1.日志框架(故事引入) 小张:开发一个大型系统: ​ 1.System.out.println(""):将关键数据打印在控制台:去掉?写在一个文件 ...

  5. 解决:虚拟机能ping通主机,主机ping不通虚拟机

    问题:虚拟机能ping通主机,主机ping不通虚拟机 解决方法: 1. 使用桥接. 2. 关闭防火墙.

  6. GRYZ 模 拟 赛 系 列 Xxy 的车厢调度

    Xxy 的车厢调度(train.cpp/c/pas)Description有 一 个 火 车 站 , 铁 路 如 图 所 示 ,每辆火车从 A 驶入,再从 B 方向驶出,同时它的车厢可以重新组合.假设 ...

  7. [转]eclipse转idea, 快捷键设置

    原文地址: eclipse转idea, 快捷键设置   设置快捷键的途径: 打开idea的配置,找到Keymap,设置为eclipse 另外还要手动设置某些快捷键 上下移动 点击类打开 代码提示 查询 ...

  8. [Java]struts2-spring整合时配置监听器

    1.struts2-spring整合时配置监听器 [在web.xml中] <!-- 上下文载入器监听器,确保web服务器启动时,直接完成spring容器的初始化 --/> [Ctrl + ...

  9. HDU 4453 Looploop (伸展树splay tree)

    Looploop Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)Total Su ...

  10. oracle 删除字段中空格

    update  sales_report set region =  REGEXP_REPLACE(region,  '( ){1,}', '')