关于spring 核心线程池满了 当并发的时候 遇到线程拒绝,统一异常处理会处理两次
先贴代码
@RequestMapping(value = "/testVisitNum", method = RequestMethod.POST, produces = {MediaType.APPLICATION_JSON_VALUE})
@ApiOperation(value = "测试访问人数过多,是否会报错两次", response = BaseVo.class)
@ApiOperationSupport(order = 3)
public Callable<ResponseEntity<JSONObject>> testVisitNum(HttpServletRequest request) {
//System.out.println(getCurrentUserId(request));
return ()->{
Thread.sleep(3000);
return success();
};
}
配置文件中
spring.task.execution.pool.allow-core-thread-timeout=true
spring.task.execution.pool.core-size=8
spring.task.execution.pool.keep-alive=60s
spring.task.execution.pool.max-size=8
spring.task.execution.pool.queue-capacity=0
spring.task.execution.shutdown.await-termination=true
spring.task.execution.shutdown.await-termination-period=1s
spring.task.execution.thread-name-prefix=hexin-
统一异常处理
@ExceptionHandler
public ResponseEntity<JSONObject> exp2(Exception ex) {
JSONObject result = new JSONObject();
if (ex instanceof TaskRejectedException) {
ex.printStackTrace();
result.put("code", NumberUtils.CODE_99);
result.put("msg", "访问人数过多,请稍后再试");
log.error("访问人数过多,请稍后再试"+ex.hashCode());
//TODO 测试 这里可能会调用多次
System.out.println("实际返回值1:"+result.toJSONString());
return new ResponseEntity<>(result, HttpStatus.OK);
}
控制台打印
访问人数过多,请稍后再试2039621435
访问人数过多,请稍后再试2039621435
hashcode是同一个
jemter 测试
导致第九个结果 反馈给客户但是 两个json对象 求解~
已经解决
@ExceptionHandler
@ResponseStatus(HttpStatus.SERVICE_UNAVAILABLE) //加了这样返回参数 状态码 解决这个问题
public ResponseEntity<JSONObject> exp2(Exception ex) {
JSONObject result = new JSONObject();
// 根据不同错误输出不同的消息
ex.printStackTrace();
result.put("code", NumberUtils.CODE_99);
result.put("msg", "访问人数过多,请稍后再试");
log.error("访问人数过多,请稍后再试"+ex.hashCode());
//TODO 测试 这里可能会调用多次
System.out.println("实际返回值1:"+result.toJSONString());
return new ResponseEntity<>(result, HttpStatus.OK);
}
debug了一下,然后结合百度的情况,先说原因,tomcat的拒绝策略并不是直接拒绝,临死前还挣扎了一次,将任务加入到等待队列,
第二次如果还是没有线程处理的话,这个就真的拒绝了,
先是百度了一下能不能去配置拒绝策略,发现并没有啥好的方式,然后退而求其次,既然是执行两次,那我控制下异常处理逻辑,只写入一次异常信息即可
加入限制前
加入限制
线上这需要你多测试测试看有没有问题