背景
大促备战,最大的危险项之一就是慢sql,带来的破坏性最大,也是日常工作中经常带来整个应用抖动的最大危险,而且对sql好坏的评价有必定的技术要求,有一些缺乏经验或许因为不够仔细形成一个坏的sql成功走到了线上,等发现的时分要么是形成了线上影响、报警、或许后置的慢sql采集发现,这时分一般无法快速止损,需求修正代码上线、或许调整数据库索引。
核心痛点:
1、无法提早发现慢sql,可能恶化为慢sql的句子
2、线上出现慢sql后,无法快速止损
处理思路
1、把问题处理在上线之前,最好的方法就是在测验阶段,甚至在开发阶段就发现一个sql的好坏
2、线上发现慢sql后除了改代码上线、调整数据库表索引的方法外,支撑热更新的方法替换sql句子。
部分内部,现在大部分数据库框架采用的mybatis,然后根据mybatis本身的完成机制中,开发一个mybatis组件,能够主动对运行的sql进行提取和剖析,定制一套默许的剖析规矩,让sql在开发环境和测验环境履行的时分,就能够做开始的评价,把有问题的慢sql在这个阶段暴露出来;一起具有sql替换功用,在线上出现问题sql的时分,能够通过ducc装备快速完成对一个sql的在线替换,大大下降线上问题的止损时刻。
开源计划调研
现在,干流的sql剖析组件,核心功用首要放在了两个方向:1、慢sql的剖析和优化主张 2、sql的优化重写功用,而且首要偏运维的辅助功用无法做到无侵入的和应用代码进行集成。也就无法完成我们的核心痛点,慢sql提早剖析预警和动态sql替换。
规划计划
核心功用:SQL剖析预警能力、SQL替换能力
详细规划
首要分为8个功用模块
模块一:core 首要负责组件的接入到mybatis,以及其它模块的编列调用
模块二:config 首要负责组件装备信息的初始化
模块三:extrat 首要通过解析mybatis 相关对象,提取完整的待履行sql
模块四:analysis 首要拼接剖析句子,履行explain剖析句子并获取剖析成果
模块五:rule sql剖析规矩的加载和初始化,支撑自定义规矩
现在默许规矩(继续扩展):
1、查询未匹配索引
2、匹配索引过滤作用较差
3、返回行数过多
4、运用了文件排序
模块六:score 根据剖析成果和装备的评分规矩进行匹配打分,优化主张组装
模块七:out 输出模块,关于输出成果进行输出,现在已error日志、MQ两种输出方法
模块八:replace替换模块,能够对sql句子根据ducc装备进行动态替换
运用方法
1、引入依赖jar包
<dependency>
<groupId>com.jd.sql.analysis</groupId>
<artifactId>sql-analysis</artifactId>
<version>1.2-SNAPSHOT</version>
</dependency>
2、装备组件xml
<configuration>
<plugins>
<plugin interceptor="com.jd.sql.analysis.core.SqlAnalysisAspect" >
<!-- 敞开sql剖析功用最简装备 -->
<property name="analysisSwitch" value="true"/>
<!-- 敞开sql替换功用最简装备 -->
<property name="sqlReplaceModelSwitch" value="true"/>
<property name="duccAppName" value="workbench-backend"/>
<property name="duccUri" value="ucc://xxxx@test.ducc.jd.local/v1/namespace/workbench_backend/config/default/profiles/test?longPolling=60000&necessary=false"/>
<property name="duccMonitorKey" value="refundBugFlag"/>
</plugin>
</plugins>
</configuration>
3、核心装备项
属性 | 用处 | 是否必填 | 默许值 | 补白 |
---|---|---|---|---|
analysisSwitch | 是否敞开剖析功用 | 是 | false | |
onlyCheckOnce | 是否对一个sqlid只剖析一次 | 非 | true | |
checkInterval | 每个sqlid剖析距离 | 非 | 300000毫秒 | onlyCheckOnce 为false才收效 |
exceptSqlIds | 需求过滤不剖析的sqlid | 非 | | |
sqlType | 剖析的sql类型 | 非 | 默许select、update | 支撑 |
scoreRuleLoadClass | 评分规矩加载器,用于扩展自定义规矩 | 非 | | |
outModel | 默许输出方法 | 非 | 默许值:LOG | 支撑LOG、MQ两种方法 |
outputClass | 评分成果输出类,用于扩展自定义成果输出方法 | 非 | | |
sqlReplaceModelSwitch | sql替换模块是否敞开 | 非 | 默许 false | |
duccAppName | ducc装备的应用名称(jdos) | 非 | | |
duccUri | ducc uri装备 | 非 | | |
duccMonitorKey | sql替换装备文件对应的key | 非 | | |
4、默许剖析作用展现
1、慢sql剖析作用
2、sql动态替换作用
5、实践运用计划
1、慢sql剖析-日志输出+关键词告警
<configuration>
<plugins>
<plugin interceptor="com.jd.sql.analysis.core.SqlAnalysisAspect" >
<property name="analysisSwitch" value="true"/>
</plugin>
</plugins>
</configuration>
2、慢sql剖析-日志输出+mq输出+es存储+Kibana剖析
<configuration>
<plugins>
<plugin interceptor="com.jd.sql.analysis.core.SqlAnalysisAspect" >
<property name="appName" value="workbench-backend"/>
<property name="analysisSwitch" value="true"/>
<property name="outputModel" value="mq"/>
<property name="mqApp" value="qlstation"/>
<property name="mqUser" value="xxx"/>
<property name="mqPassword" value="xxx"/>
<property name="mqAddress" value="jmq-testcluster.jd.local:50088"/>
<property name="mqTopic" value="jdl_kds_key_node_log"/>
</plugin>
</plugins>
</configuration>
终究作用
3、慢sql替换-ducc装备动态更新sql句子
<configuration>
<plugins>
<plugin interceptor="com.jd.sql.analysis.core.SqlAnalysisAspect" >
<property name="sqlReplaceModelSwitch" value="true"/>
<property name="duccAppName" value="workbench-backend"/>
<property name="duccUri" value="ucc://xxx/v1/namespace/workbench_backend/config/default/profiles/test?longPolling=60000&necessary=false"/>
<property name="duccMonitorKey" value="sqlReplaceConfig"/>
</plugin>
</plugins>
</configuration>
发现慢sql
ducc装备
线上sql被动态替换
留意:功用正式修正后,需去掉该装备,该功用仅供应急处理线上问题,不主张作为功用长期运用
性能测验
测验环境千次一般sql查询,每种场景进行了5次测验
未启用插件耗时:11108ms,10237ms,9482ms,7938ms,8196ms
敞开sql剖析耗时:16619ms,17333ms,16321ms,19057ms,18164ms
实际装备,只要首次履行或许距离时刻履行,单次影响10ms左右)
敞开sql替换耗时:10642ms,8803ms,8353ms,8830ms,9170ms
基本无影响
适用场景
1、慢sql防备
2、线上问题止损
优势
1、核心优势:履行时剖析sql,区别于传统的依赖sql履行耗时来评价慢sql,直接根据语法和索引进行前置剖析,不仅能防备某些坏sql在上线后发现是慢sql,还能给出sql优化主张,能够大极限的避免线上产生慢sql。支撑动态对线上sql进行替换,能够对线上问题快速止损。
2、性能:根据性能和不同的运用场景考虑,支撑定制化装备,每个sql是否仅进行一次查看、或许按某个时刻距离进行装备。sql替换简直无损耗。
3、扩展:根据后续sql评分规矩的扩展、以及剖析成果以不同的方法输出的考虑,支撑评分规矩、输出方法的自定义扩展。
4、本钱:接入本钱低,无代码侵入。
作者:京东物流 扈海涛
来源:京东云开发者社区