背景

大促备战,最大的危险项之一就是慢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替换。

Mybatis-SQL分析组件 | 京东云技术团队

规划计划

核心功用:SQL剖析预警能力、SQL替换能力

Mybatis-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剖析作用

Mybatis-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>

终究作用

Mybatis-SQL分析组件 | 京东云技术团队

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

Mybatis-SQL分析组件 | 京东云技术团队

ducc装备

Mybatis-SQL分析组件 | 京东云技术团队

线上sql被动态替换

Mybatis-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、本钱:接入本钱低,无代码侵入。

作者:京东物流 扈海涛

来源:京东云开发者社区