添加线程池拒绝策略

This commit is contained in:
yuye
2019-04-14 14:42:52 +08:00
parent 1ded0a7359
commit bea673a3ea
12 changed files with 121 additions and 51 deletions
@@ -65,4 +65,9 @@ public class EasyConstant {
* 读取远程配置的路径
*/
public static final String READ_REMOTE_CONFIG = "http://${0}/getConfig";
/**
* 方法返回值为void的标记
*/
public static final String VOID = "void405cb55d6781877e9e930aa8e046098b";
}
@@ -2,12 +2,9 @@ package com.mars.core.util;
import com.alibaba.fastjson.JSONObject;
import com.mars.core.constant.EasyConstant;
import io.codearte.props2yaml.PropertyTree;
import io.codearte.props2yaml.Props2YAML;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
public class RemoteConfigUtil {
@@ -1,5 +1,6 @@
package com.mars.mvc.resolve;
import com.mars.core.constant.EasyConstant;
import com.mars.mvc.base.BaseInterceptor;
import com.mars.core.logger.MarsLogger;
import com.mars.core.util.MesUtil;
@@ -76,7 +77,7 @@ public class ExecuteEasy {
Object result = null;
if(st.toLowerCase().trim().equals("void")){
method2.invoke(obj, new Object[] { request, response });
result = "void405cb55d6781877e9e930aa8e046098b";
result = EasyConstant.VOID;
} else {
result = method2.invoke(obj, new Object[] { request, response });
}
@@ -44,7 +44,6 @@ public class ExecuteInters {
return result;
}
}
return BaseInterceptor.SUCCESS;
} catch (Exception e) {
logger.error("执行拦截器报错,拦截器类型["+clss.getName()+"]",e);
@@ -60,7 +59,7 @@ public class ExecuteInters {
* @param response xiangying
* @return duix
*/
public static Object executeIntersEnd(List<Object> list,HttpRequest request, HttpResponse response,Object objs) {
public static Object executeIntersEnd(List<Object> list,HttpRequest request, HttpResponse response,Object conResult) {
Class<?> clss = null;
try {
@@ -68,7 +67,7 @@ public class ExecuteInters {
clss = obj.getClass();
Method method2 = clss.getDeclaredMethod("endRequest", new Class[] { HttpRequest.class, HttpResponse.class, Object.class });
Object result = method2.invoke(obj, new Object[] { request, response, objs });
Object result = method2.invoke(obj, new Object[] { request, response, conResult });
if(!result.toString().equals(BaseInterceptor.SUCCESS)) {
return result;
}
@@ -115,7 +114,7 @@ public class ExecuteInters {
return new ArrayList<>();
}
}
/**
* 返回错误信息
* @param cls
@@ -33,7 +33,6 @@ public class LoadController {
/**
* 创建controller对象,并将服务层对象注入进去
*/
@SuppressWarnings("unchecked")
public static void loadContrl() throws Exception{
try {
@@ -1,14 +1,12 @@
package com.mars.netty.server;
import com.mars.core.logger.MarsLogger;
import com.mars.core.util.MesUtil;
import com.mars.netty.thread.RequestThread;
import com.mars.netty.thread.ThreadPool;
import com.mars.server.server.request.HttpResponse;
import com.mars.netty.util.ResponseUtil;
import io.netty.channel.ChannelHandlerAdapter;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
import io.netty.handler.timeout.IdleStateEvent;
import java.net.InetAddress;
@@ -41,15 +39,16 @@ public class EasyServerHandler extends ChannelHandlerAdapter {
requestThread.setCtx(ctx);
ThreadPool.execute(requestThread);
} else {
sendBad(ctx,"处理请求发生错误");
ResponseUtil.sendServerError(ctx,"处理请求发生错误");
}
} catch (Exception e) {
log.error("处理请求失败!", e);
sendBad(ctx,"处理请求发生错误"+e);
ResponseUtil.sendServerError(ctx,"处理请求发生错误"+e);
/* 已经通过线程中的finally 释放请求了,所以这里,在出异常的时候,才释放 */
try {
ctx.close();
httpRequest.release();
} catch (Exception e2) {
}
@@ -80,33 +79,14 @@ public class EasyServerHandler extends ChannelHandlerAdapter {
switch (idleStateEvent.state()){
case READER_IDLE:
sendTimeout(ctx,"请求超时");
ResponseUtil.sendTimeout(ctx,"请求超时");
break;
case WRITER_IDLE:
sendTimeout(ctx,"请求超时");
ResponseUtil.sendTimeout(ctx,"请求超时");
break;
default:
super.userEventTriggered(ctx, evt);
}
}
}
/**
* 响应
* @param ctx
*/
private void sendBad(ChannelHandlerContext ctx,String ex){
HttpResponse response = new HttpResponse(ctx);
response.send(MesUtil.getMes(500,ex).toJSONString(), HttpResponseStatus.BAD_REQUEST);
}
/**
* 响应请求超时
* @param ctx
*/
private void sendTimeout(ChannelHandlerContext ctx,String ex){
HttpResponse response = new HttpResponse(ctx);
response.send(MesUtil.getMes(503,ex).toJSONString(), HttpResponseStatus.BAD_REQUEST);
}
}
@@ -1,5 +1,6 @@
package com.mars.netty.server;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mars.core.util.ConfigUtil;
import io.netty.channel.ChannelInitializer;
@@ -17,7 +18,8 @@ import io.netty.handler.timeout.IdleStateHandler;
*/
public class EasyServerInitializer extends ChannelInitializer<SocketChannel> {
private int timeOut = 10;
private int readTimeOut = 10;
private int writeTimeOut = 2000000000;
private int maxContentLength = 10485760;
@Override
@@ -37,7 +39,7 @@ public class EasyServerInitializer extends ChannelInitializer<SocketChannel> {
private IdleStateHandler getIdleStateHandler(){
return new IdleStateHandler(timeOut,2000000000,0);
return new IdleStateHandler(readTimeOut,writeTimeOut,0);
}
private HttpObjectAggregator getHttpObjectAggregator(){
@@ -51,15 +53,24 @@ public class EasyServerInitializer extends ChannelInitializer<SocketChannel> {
private void getConfig() {
JSONObject jsonObject = ConfigUtil.getConfig();
Object timeOuto = jsonObject.get("timeOut");
Object maxContentLengtho = jsonObject.get("maxContentLength");
Object timeOut = jsonObject.get("timeOut");
Object maxContentLength2 = jsonObject.get("maxContentLength");
if(timeOuto!=null) {
timeOut = Integer.parseInt(timeOuto.toString());
if(timeOut != null){
JSONObject timeOut2 = JSONObject.parseObject(JSON.toJSONString(timeOut));
Object readTimeOut2 = timeOut2.get("readTimeOut");
Object writeTimeOut2 = timeOut2.get("writeTimeOut");
if(readTimeOut2!=null) {
readTimeOut = Integer.parseInt(readTimeOut2.toString());
}
if(writeTimeOut2!=null) {
writeTimeOut = Integer.parseInt(writeTimeOut2.toString());
}
}
if(maxContentLengtho != null){
maxContentLength = Integer.parseInt(maxContentLengtho.toString());
if(maxContentLength2 != null){
maxContentLength = Integer.parseInt(maxContentLength2.toString());
}
}
}
@@ -0,0 +1,25 @@
package com.mars.netty.thread;
import com.mars.netty.util.ResponseUtil;
import java.util.concurrent.RejectedExecutionHandler;
import java.util.concurrent.ThreadPoolExecutor;
/**
* 请求过多的拒绝策略
*/
public class MarsRejectedExecutionHandler implements RejectedExecutionHandler {
/**
* 拒绝策略
* @param r
* @param executor
*/
@Override
public void rejectedExecution(Runnable r, ThreadPoolExecutor executor) {
if(r instanceof RequestThread){
RequestThread requestThread = (RequestThread)r;
ResponseUtil.sendForBidden(requestThread.getCtx(),"当前请求太多,请稍后访问");
}
}
}
@@ -1,6 +1,7 @@
package com.mars.netty.thread;
import com.alibaba.fastjson.JSON;
import com.mars.core.constant.EasyConstant;
import com.mars.core.constant.EasySpace;
import com.mars.core.logger.MarsLogger;
import com.mars.core.util.MesUtil;
@@ -8,6 +9,7 @@ import com.mars.server.server.request.HttpRequest;
import com.mars.server.server.request.HttpResponse;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.FullHttpRequest;
import io.netty.handler.codec.http.HttpResponseStatus;
import java.lang.reflect.Method;
@@ -35,6 +37,10 @@ public class RequestThread implements Runnable {
this.ctx = ctx;
}
public ChannelHandlerContext getCtx() {
return ctx;
}
public void run() {
/* 组装httprequest对象 */
@@ -55,7 +61,7 @@ public class RequestThread implements Runnable {
Object object = cls.getDeclaredConstructor().newInstance();
Method helloMethod = cls.getDeclaredMethod("doRequest", new Class[] { HttpRequest.class ,HttpResponse.class});
Object result = helloMethod.invoke(object, new Object[] { request ,response});
if(result != null && result.toString().equals("void405cb55d6781877e9e930aa8e046098b")) {
if(result != null && result.toString().equals(EasyConstant.VOID)) {
return;
}
/* 将控制层返回的数据,转成json字符串返回 */
@@ -65,8 +71,13 @@ public class RequestThread implements Runnable {
log.error("处理请求的时候出错",e);
response.send(MesUtil.getMes(500,"处理请求发生错误"+e).toJSONString());
} finally {
// 释放请求
httpRequest.release();
try{
// 释放请求
ctx.close();
httpRequest.release();
} catch (Exception e){
log.error("释放请求出错",e);
}
}
}
}
@@ -3,6 +3,8 @@ package com.mars.netty.thread;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.mars.core.util.ConfigUtil;
import com.mars.netty.util.ResponseUtil;
import io.netty.channel.ChannelHandlerContext;
import java.util.concurrent.*;
@@ -23,8 +25,6 @@ public class ThreadPool {
private static int keepAliveTime = 60;
/**
* 新增请求的线程
* @param command
@@ -33,7 +33,7 @@ public class ThreadPool {
if(pool == null){
init();
workQueue = new ArrayBlockingQueue<>(maximumPoolSize - corePoolSize);
pool = new ThreadPoolExecutor(corePoolSize,maximumPoolSize, keepAliveTime,TimeUnit.SECONDS,workQueue);
pool = new ThreadPoolExecutor(corePoolSize,maximumPoolSize, keepAliveTime,TimeUnit.SECONDS,workQueue,new MarsRejectedExecutionHandler());
}
pool.execute(command);
}
@@ -0,0 +1,40 @@
package com.mars.netty.util;
import com.mars.core.util.MesUtil;
import com.mars.server.server.request.HttpResponse;
import io.netty.channel.ChannelHandlerContext;
import io.netty.handler.codec.http.HttpResponseStatus;
/**
* 响应工具类
*/
public class ResponseUtil {
/**
* 禁止访问响应
* @param ctx
*/
public static void sendForBidden(ChannelHandlerContext ctx, String ex){
HttpResponse response = new HttpResponse(ctx);
response.send(MesUtil.getMes(403,ex).toJSONString(), HttpResponseStatus.OK);
}
/**
* 出错响应
* @param ctx
*/
public static void sendServerError(ChannelHandlerContext ctx, String ex){
HttpResponse response = new HttpResponse(ctx);
response.send(MesUtil.getMes(500,ex).toJSONString(), HttpResponseStatus.OK);
}
/**
* 请求超时响应
* @param ctx
*/
public static void sendTimeout(ChannelHandlerContext ctx,String ex){
HttpResponse response = new HttpResponse(ctx);
response.send(MesUtil.getMes(503,ex).toJSONString(), HttpResponseStatus.OK);
}
}
@@ -4,8 +4,10 @@
port: 8088
#配置jwt有效期(默认1),单位:天
jwtTime: 20
#请求超时时间(默认10),单位:秒
timeOut: 10
#请求超时时间(默认10,2000000000),单位:秒
timeOut:
readTimeOut: 10
writeTimeOut: 2000000000
#请求数据的最大值(默认10485760)
maxContentLength: 10
#配置跨域请求