使用 SpringCloud(Gateway) + Skywalking + Mysql 做分布式跟踪

本文涉及源码都在 这里

Apache Skywalking(Incubator)简介

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

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

英文版文档:https://github.com/apache/skywalking/blob/master/docs/README.md
中文版文档:https://skyapm.github.io/document-cn-translation-of-skywalking/

下载并安装

下载

官网 下载合适的压缩包,如果下载失败(不知道为啥我下载下来的是个空包),可以直接在这个 镜像网站 下载。.zip 格式是 Windows 版本,.tar.gzLinux 版本, 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
...

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

这时访问 http://localhost:8080/ 即可看到如下页面:

监控页面

至此,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_namevalue 其实是占位符,优先使用 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),等过一段时间后会自动清清除。

请求追踪

多次访问 http://localhost:3100/licence/1,然后切到 追踪 标签页,可以看到类似如下:

trace with failed request

正常的请求长这样:
trace

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

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

使用 optional-plugins

兼容 SpringCloud Gateway

前面提到,agent 目录下有 pluginsoptional-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 目录下。

最后,重启4个服务,再访问 http://localhost:3100/licence/1,可以看到如下:

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 参数配置。

最后,重启4个服务,再访问 http://localhost:3100/licence/1,可以看到如下:

ignore path

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

相关配置可参考:支持忽略自定义的traceSupport custom trace ignore

相关链接

官网:https://skywalking.apache.org/
英文版文档:https://github.com/apache/skywalking/blob/master/docs/README.md
中文版文档:https://skyapm.github.io/document-cn-translation-of-skywalking/
配置覆盖:https://skyapm.github.io/document-cn-translation-of-skywalking/zh/master/setup/service-agent/java-agent/Setting-override.html

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 158,847评论 4 362
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 67,208评论 1 292
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 108,587评论 0 243
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 43,942评论 0 205
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 52,332评论 3 287
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 40,587评论 1 218
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 31,853评论 2 312
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 30,568评论 0 198
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 34,273评论 1 242
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 30,542评论 2 246
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 32,033评论 1 260
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 28,373评论 2 253
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 33,031评论 3 236
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 26,073评论 0 8
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 26,830评论 0 195
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 35,628评论 2 274
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 35,537评论 2 269

推荐阅读更多精彩内容