需求
1、监控应用层SQL执行时间,超过阈值的视为慢SQL,广播慢SQL事件
2、日志记录慢SQL完整内容以及服务层调用堆栈信息
3、监控慢SQL事件并发出预警信息,例如:邮件、短信、向企业微信发送消息
总体设计图
实现
原理是通过扩展Druid连接池的com.alibaba.druid.filter.stat.StatFilter实现,下面是对Druid的扩展实现慢SQL异常事件的告警
1)过滤器的增强
@Slf4j
public class MyDruidFilter extends StatFilter {
@Override
protected void handleSlowSql(StatementProxy statement) {
//耗时 毫秒
long millis = statement.getLastExecuteTimeNano() 1000000L;
//sql参数
String slowParameters = this.buildSlowParameters(statement);
//sql语句
String lastExecSql = statement.getLastExecuteSql();
//推送告警
ApplicationEventPublisher bean = SpringUtil.getApplicationEventPublisher();
HealthCheckConfig config = SpringUtil.getBean(HealthCheckConfig.class);
if (millis>=config.getHealthCheckSlowSqlMaxTime()) {
SlowSqlEvent.SlowSqlDto slowSqlDto = new SlowSqlEvent.SlowSqlDto();
slowSqlDto.setSlowParameters(slowParameters);
slowSqlDto.setCostTime(millis);
slowSqlDto.setSlowSql(lastExecSql);
//获取调用栈信息
slowSqlDto.setStackTraceElements(Thread.currentThread().getStackTrace());
bean.publishEvent(new SlowSqlEvent(slowSqlDto));
}
//log.error("slow sql " + millis + " millis. " + lastExecSql + "" + slowParameters);
}
}
复制
2)连接池配置应用增强后的过滤器
<bean id="dataSource" class="com.alibaba.druid.pool.DruidDataSource" destroy-method="close">
<property name="url" value="${jdbc.url}" >
<property name="username" value="${jdbc.username}" />
<property name="password" value="${jdbc.password}" />
<property name="proxyFilters">
<list>
<!--慢SQL-->
<bean id="stat-filter" class="com.xxx.xxx.MyDruidFilter">
<property name="slowSqlMillis" value="1000" />
<property name="logSlowSql" value="true" />
<property name="mergeSql" value="true" />
</bean>
</list>
</property>
</bean>
复制
总结
1、慢SQL监控的实现方式:1)应用侧的连接池 2)数据库服务端
2、应用侧监控慢SQL的优势是可以实现对服务层调用栈的记录,利于业务开发人员更快的定位问题
今天就到这里,感谢大家关注老吕架构!
文章转载自老吕架构,如果涉嫌侵权,请发送邮件至:contact@modb.pro进行举报,并提供相关证据,一经查实,墨天轮将立刻删除相关内容。