skywalking适配mysql

背景

  • 为了去抓取应用端发来的负载信息,比如sql,timestamp,sql中的para,和select语句的result集合,通过分析这些负载,来模拟负载,主要用于抓取应用端的负载,相当于数据挖掘中获取数据的来源把~~

  • 这篇主要是总结我在适配skywalking获取mysql应用端的负载遇到的问题和感受。

先行

  • 利用skywalking在以mysql为数据库的应用程序中抓取负载,在实验中,以oltpbench为应用端。大致的配置是,在https://github.com/apache/skywalking拉去skywalking源代码,利用说明文档进行编译

    1
    2
    3
    4
    5
    git clone https://github.com/apache/skywalking.git
    cd skywalking/
    git submodule init
    git submodule update
    ./mvnw clean package -DskipTests
  • 编译好的在dist目录下,如果没有别的需求,可直接在启动应用端的脚本或命令行中加入-javaagent /skywalking/agent/skywalking-agent.jar。

  • 由于项目中需要按照一定的形式将抓取到的日志输入固定的文件中,因此主要对skywalking的三个包进行修改,分别是mysql-common,mysql-5.x,jdbc-commons,这三个都在./apm-sniffer/apm-sdk-plugins中。

操作

mysql-commons

  • 里面都是一些截流器,有针对预编译sql的PreparadStatementExeucute,还有PreparadStatementBatchExeucute,和普通的StateExecute。这些截流器都被注册了,与mysql-5.x中的注册器对应,注册器指明mysql中哪里函数利用那些截流器去捕获。如”add batch”函数就利用PreparadStatementBatchExeucute去抓取。”executeUpdate”利用PreparadStatementExeucute和StateExecute去抓取(根据不同的sql类型)

mysql-5.x

  • 一些注册器,与拦截器对应即可

jdbc-commons

  • 主要是加了connId,还有与commit,rollback有关的拦截器,在这个包中,也进行了修改。

问题

mysql 的 jdbc重复调用问题

  • 查看Mysql的jdbc的包(可利用反编译软件进行查看),发现add batch又调用了executeUpdate函数,导致skywalking抓包的时候重复捕获一条语句,导致重复。此外,还有executeUpdate自调用三次,导致一条日志被打印出三次。这类问题的处理方式,利用查看调用栈,分析它的调用过程,来忽略一些日志的输出。

  • 1
    2
    3
    4
    5
    6
    7
    8
    9
    Exception ex = new Exception();
    StackTraceElement[] ste = ex.getStackTrace();
    boolean fromExecuteBatch = false;
    for (int i = 0; i < ste.length; ++i) {
    if(ste[i].getMethodName().contains("executeBatch")||ste[i].getMethodName().contains("executeUpdate$Original")){
    fromExecuteBatch = true;
    break;
    }
    }

mysql中以一个host为一个connId

  • 由于项目的需要,我们需要得到connId,在jdbc-commons的相应位置加上与connId相关的代码。
  • 但是发现createstatement有个问题,就是无论多少个线程,以及无论多少个连接,但输出总是一个相同的。但从mysql端捕获到的connectionInfo都是不同的,后来发现是skywalking中是根据host和Port来存储connectionInfo的,若从相同的host和port发送数据库请求,那skywalking(mysql部分,oracle应该不是这样的)就认为是用一条connectionInfo信息,导致出错。
  • 这个问题的解决方法:就不用host和port进行存储..换了另一种方式。

总结

  • skywalking适配mysql耗时达1周左右,发现自己还是畏惧源码的阅读,无论是skywalking还是mysql-jdbc还是不能有效的进行阅读,希望下次能改进。
  • 自己对于问题的解决不能深入,抱着懒散的心态~,要加油呀!
0%