skywalking监控mysql_使用 SpringCloud(Gateway) + Skywalking + Mysql 做分布式跟踪

本文涉及源码都在 这里。

Apache Skywalking(Incubator)简介

Apache Skywalking(Incubator) 专门为微服务架构和云原生架构系统而设计并且支持分布式链路追踪的APM系统。Apache Skywalking(Incubator)通过加载探针的方式收集应用调用链路信息,并对采集的调用链路信息进行分析,生成应用间关系和服务间关系以及服务指标。Apache Skywalking (Incubating)目前支持多种语言,其中包括Java,.Net Core,Node.js和Go语言。

目前Skywalking已经支持从6个可视化维度剖析分布式系统的运行情况。总览视图是应用和组件的全局视图,其中包括组件和应用数量,应用的告警波动,慢服务列表以及应用吞吐量;拓扑图从应用依赖关系出发,展现整个应用的拓扑关系;应用视图则是从单个应用的角度,展现应用的上下游关系,TopN的服务和服务器,JVM的相关信息以及对应的主机信息。服务视图关注单个服务入口的运行情况以及此服务的上下游依赖关系,依赖度,帮助用户针对单个服务的优化和监控;调用链展现了调用的单次请求经过的所有埋点以及每个埋点的执行时长;告警视图根据配置阈值针对应用、服务器、服务进行实时告警。

下载并安装

下载

从官网 下载合适的压缩包,如果下载失败(不知道为啥我下载下来的是个空包),可以直接在这个 镜像网站 下载。.zip 格式是 Windows 版本,.tar.gz 是 Linux 版本, Mac 也用 .tar.gz 。

本次使用的是目前最新稳定版 v6.6.0,而且到时使用 Mysql 做数据存储,所以我下载的是这个 压缩包 。

解压

解压压缩包:

tar -zxvf apache-skywalking-apm-6.6.0.tar.gz

大致目录树结构如下:

解压后的目录结构

简单说一下这几个目录的作用:

webapp: UI 前端(web 监控页面)的 jar 包和配置文件;

oap-libs: 后台应用的 jar 包,以及它的依赖 jar 包,里边有一个 server-starter-*.jar 就是启动程序;

config: 启动后台应用程序的配置文件,是使用的各种配置

bin: 各种启动脚本,一般使用脚本 startup.* 来启动 web 页面 和对应的 后台应用;

oapService.*: 默认使用的后台程序的启动脚本;(使用的是默认模式启动,还支持其他模式,各模式区别见 启动模式)

oapServiceInit.*: 使用 init 模式启动;在此模式下,OAP服务器启动以执行初始化工作,然后退出

oapServiceNoInit.*: 使用 no init模式启动;在此模式下,OAP服务器不进行初始化。

webappService.*: UI 前端的启动脚本;

startup.*: 组合脚本,同时启动 oapService.*:、webappService.* 脚本;

agent:

skywalking-agent.jar: 代理服务 jar 包

config: 代理服务启动时使用的配置文件

plugins: 包含多个插件,代理服务启动时会加载改目录下的所有插件(实际是各种 jar 包)

optional-plugins: 可选插件,当需要支持某种功能时,比如 SpringCloud Gateway,则需要把对应的 jar 包拷贝到 plugins 目录下;

启动后端服务和前端UI

Skywalking 的后端服务默认使用的数据库是 h2,而我们需要使用的是 Mysql,所以得修改部分配置。该配置文件是目录 config 下的 application.yml 文件,将 h2 数据库相关配置注释掉,然后 Mysql 部分去掉注释,并将数据库名、账号密码修改一下。修改完大致如下:

storage:

... 省略部分

# h2:

# driver: ${SW_STORAGE_H2_DRIVER:org.h2.jdbcx.JdbcDataSource}

# url: ${SW_STORAGE_H2_URL:jdbc:h2:mem:skywalking-oap-db}

# user: ${SW_STORAGE_H2_USER:sa}

# metadataQueryMaxSize: ${SW_STORAGE_H2_QUERY_MAX_SIZE:5000}

mysql:

properties:

jdbcUrl: ${SW_JDBC_URL:"jdbc:mysql://localhost:3306/skywalking"}

dataSource.user: ${SW_DATA_SOURCE_USER:root}

dataSource.password: ${SW_DATA_SOURCE_PASSWORD:root}

dataSource.cachePrepStmts: ${SW_DATA_SOURCE_CACHE_PREP_STMTS:true}

dataSource.prepStmtCacheSize: ${SW_DATA_SOURCE_PREP_STMT_CACHE_SQL_SIZE:250}

dataSource.prepStmtCacheSqlLimit: ${SW_DATA_SOURCE_PREP_STMT_CACHE_SQL_LIMIT:2048}

dataSource.useServerPrepStmts: ${SW_DATA_SOURCE_USE_SERVER_PREP_STMTS:true}

metadataQueryMaxSize: ${SW_STORAGE_MYSQL_QUERY_MAX_SIZE:5000}

注:如果没有创建 skywalking 数据库,还需要手动创建。

因为 oap-libs 目录下缺少 mysql 的驱动程序,所以还需要下载 mysql-connector-java-*.jar 放到 oap-libs 目录下,这里我使用的版本是 5.1.46。一般该 jar 包在本地的 maven 仓库都有,直接拷贝过去即可,一般在目录 ~/.m2/repository/mysql/mysql-connector-java/5.1.46 下。

$ cd apache-skywalking-apm-bin/bin

# 启动

$ ./startup.sh

SkyWalking OAP started successfully!

SkyWalking Web Application started successfully!

# 查看启动的服务

$ jps

17716 RemoteMavenServer

16005 Launcher

4295 OAPServerStartUp

18266 Jps

4301 skywalking-webapp.jar

...

如果看到 OAPServerStartUp 和 skywalking-webapp.jar,那么代表2个服务都启动成功。

监控页面

至此,Skywalking 的监控跟踪服务就准备完毕。

跟踪分布式服务

从 这里 克隆到本地,本文用到的子项目为 spring-cloud-advance-skywalking,进入该目录,可以看到包含如下服务:

目录结构

sca-skywalking-discovery:服务发现

sca-skywalking-gateway:网关

sca-skywalking-licence:licence 服务。里边部分接口回调用 organization 服务的接口。

sca-skywalking-organization:organization 服务。

启动服务

在 安装Java agent 中,提到了在启动应用之前,需要配置JVM参数,添加 -javaagent:/path/to/skywalking-package/agent/skywalking-agent.jar。为了方便这里以在 IDEA 中启动服务为例:

edit configurations

add jvm params

仪表盘(Dashboard)

启动4个服务后,再次访问 http://localhost:8080/ ,可以看到类似如下:

dashboard

拓扑图(Topology)

再看下拓扑图:

topology

Your_Application_Name: 服务名

localhost-1: 数据库。因为服务 licence-service, organization 使用了 H2 数据库

User: 暂时不知道是干啥的,以后知道了再补充(难道是skywalking的用户服务?)

那么问题来了,为什么启动了4个服务,这里只有一个 Your_Application_Name 服务?

其实在 安装Java agent 中,有提到需要配置 config/agent.config 中的 agent.service_name。但我们这里需要启动的服务有多个,直接配置在文件中肯定不合适,难道启动一个服务改一次?

我们先来看下 config/agent.config 中的 agent.service_name 配置,如下:

# The service name in UI

agent.service_name=${SW_AGENT_NAME:Your_ApplicationName}

... 省略前后其他配置

可以看到,属性 agent.service_name 的 value 其实是占位符,优先使用 SW_AGENT_NAME 的值,那这个到底是什么呢?其实是环境变量,如果启动时环境变量 SW_AGENT_NAME 有值的话,那么使用它,否则使用默认值 Your_ApplicationName。

所以这就不难解释在拓扑图中看到的只有一个 Your_ApplicationName,因为所有服务启动时,都使用了同一份 agent.config 配置,skywalking 认为这4个服务都是服务名为 Your_ApplicationName 的4个实例。

所以我们可以在启动时配置一下环境变量即可。如下:

add env variables

把4个服务都配置了 SW_AGENT_NAME 环境变量后,重新启动。

再看下拓扑图,会变成下面这样:

topology

这样就比较符合我们的预期了。因为 skywalking 有一定缓存机制,当服务不可用后,不会立即删除(Your_ApplicationName),等过一段时间后会自动清清除。

请求追踪

trace with failed request

正常的请求长这样:

trace

可以看到,一个请求的所有调用链都被记录下来,包括 Spring MVC 的内部转发、跨服务的 http 调用以及数据库查询,都完整的记录下来,而且也记录了整个请求以及各个子步骤的耗时。

但是,有2个问题,第一,为啥没有记录网关层的调用链?第二,我刚刚其实只请求了几次,为什么会有151页数据?带着这2个问题,我们继续挖掘 Skywalking 的新特性。

使用 optional-plugins

兼容 SpringCloud Gateway

前面提到,agent 目录下有 plugins 和 optional-plugins 2个目录,skywalking-agent.jar 在启动时会加载 plugins 下的所有插件,但不会加载 optional-plugins 下的,其实看目录名就知道了,可选插件 就是可有可没有,需要等需要的时候再加到 plugins 下即可。

我们看到, optional-plugins 下就有跟 SpringCloud Gateway 相关的插件,那就它了,把它丢到 plugins 目录下。

image.png

但是又有一个问题,为什么 SpringCloud Gateway 这么特殊呢,为啥没一个类似 apm-spring-cloud-zuul-plugin-6.6.0.jar 的插件呢?这2个网关有啥本质上的区别吗?肯定有的啦,一个是同步的,另一个是异步(底层用了 netty,还依赖 spring-webflux)。另外,我们还注意到另一个插件 apm-spring-webflux-5.x-plugin-6.6.0.jar,把它也丢到 plugins 目录下。

trace with springcloud gateway

这样,第一个问题就解决了。

自定义忽略追踪部分请求

首先,我们不妨跳到50页,如下:

image.png

可以看到所有都是跟 eureka 相关,看到这里,如果你比较熟悉 eureka 的底层逻辑,那么基本就能猜出来啥原因了:EurekaClient 每隔一段时间都会向 EurekaServer 请求续约,也可以理解为心跳,还有定时从 EurekaServer 拉取最新的可用的服务清单。

这种记录这些请求对我们来说用处不大,而且还会造成大量垃圾数据,所以应该避免追踪,但 Skywalking 并不能自己识别出来,拿只能我们教它怎么分辨了。

注意到,optional-plugins 中有这样的插件 apm-trace-ignore-plugin-6.6.0.jar,把它丢到 plugins 目录下先。

加上插件只是让 Skywalking 拥有忽略某些请求的能力,但还需要我们指定哪些需要忽略。下载 配置文件,然后把它丢到 /agent/config/ 目录下,增加过滤规则。里边的内容如下:

# If the operation name of the first span is matching, this segment should be ignored

# ant path match style

# /path/? Match any single character

# /path/* Match any number of characters

# /path/** Match any number of characters and support multilevel directories

# Multiple path comma separation, like trace.ignore_path=/eureka/**,/consul/**

#trace.ignore_path=${SW_AGENT_TRACE_IGNORE_PATH:/eureka/**}

可以看到插件的开发者已经帮我们考虑到 eureka 这种情况了,直接去掉最后一行的注释即可,当然,也可以跟服务名一样使用环境变量配置。另外,eureka-server 因为不是我们的业务服务,所以可以考虑不对它进行代理,即去掉 JVM 参数配置。

ignore path

可以看到清爽很多,没有太多冗余的请求。

相关链接

你可能感兴趣的:(skywalking监控mysql_使用 SpringCloud(Gateway) + Skywalking + Mysql 做分布式跟踪)