mirror of
https://github.com/wahyd4/Martian.git
synced 2026-08-09 05:16:21 +10:00
⚡ 添加线程池拒绝策略
This commit is contained in:
@@ -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
|
||||
#配置跨域请求
|
||||
|
||||
Reference in New Issue
Block a user