其他
一条失去条件的动态 SQL,到手的年终奖飞了
The following article is from 小黑十一点半 Author 楼下小黑哥
# 前言
Caused by: java.util.concurrent.RejectedExecutionException: Thread pool is EXHAUSTED! Thread Name: DubboServerHandler-xxip, Pool Size: 200 (active: 200, core: 200, max: 200, largest: 200), Task: 165633 (completed: 165433), Executor status:(isShutdown:false, isTerminated:false, isTerminating:false), in 1!
at com.alibaba.dubbo.common.threadpool.support.AbortPolicyWithReport.rejectedExecution(AbortPolicyWithReport.java:53)
at java.util.concurrent.ThreadPoolExecutor.reject(ThreadPoolExecutor.java:768)
at java.util.concurrent.ThreadPoolExecutor.execute(ThreadPoolExecutor.java:656)
at com.alibaba.dubbo.remoting.transport.dispatcher.all.AllChannelHandler.caught(AllChannelHandler.java:65)
如上所示,日志中打印大量的 Dubbo 线程池线程耗尽,直接拒绝服务调用的日志登上另一台机器,好家伙,除了上述日志以外,仔细翻看居然还发生 「OOM」!
Order order=new Order();
log.info("订单查询参数信息:{}",order);
// 其他系统逻辑,关键信息数据加密等
List<Order> orderList = orderMapper.query(order);
// .. 其他查询逻辑
<select id="query" parameterType="order" resultMap="orderResultMap">
select orderId,amt,orderInfo // 还有其他信息
from
Order
<where>
<if test="orderId != null">
orderId = #{orderId}
</if>
<if test="amt != null">
AND amt = #{amt}
</if>
..... 其他条件
</where>
</select>
# 扩展思考
# 解决办法
@Intercepts({
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class,
RowBounds.class, ResultHandler.class}),
@Signature(type = Executor.class, method = "query", args = {MappedStatement.class, Object.class,
RowBounds.class, ResultHandler.class, CacheKey.class, BoundSql.class}),
@Signature(type = Executor.class, method = "update", args = {MappedStatement.class,
Object.class})})
@Slf4j
public class CheckWhereInterceptor implements Interceptor {
private static final String WHERE = "WHERE";
@Override
public Object intercept(Invocation invocation) throws Throwable {
//获取方法的第0个参数,也就是MappedStatement。@Signature注解中的args中的顺序
MappedStatement mappedStatement = (MappedStatement) invocation.getArgs()[0];
//获取sql命令操作类型
SqlCommandType sqlCommandType = mappedStatement.getSqlCommandType();
final Object[] queryArgs = invocation.getArgs();
final Object parameter = queryArgs[1];
BoundSql boundSql = mappedStatement.getBoundSql(parameter);
String sql = boundSql.getSql();
if (Objects.equals(SqlCommandType.DELETE, sqlCommandType)
|| Objects.equals(SqlCommandType.UPDATE, sqlCommandType)
|| Objects.equals(SqlCommandType.SELECT, sqlCommandType)) {
//格式化sql
sql = sql.replace("\n", "");
if (!StringUtils.containsIgnoreCase(sql, WHERE)) {
sql = sql.replace(" ", "");
log.warn("SQL 语句没有where条件,禁止执行,sql为:{}", sql);
throw new Exception("SQL语句中没有where条件");
}
}
Object result = invocation.proceed();
return result;
}
@Override
public Object plugin(Object target) {
return Plugin.wrap(target, this);
}
@Override
public void setProperties(Properties properties) {
}
}