前言

随着互联网技术的发展,系统的架构也都从单一架构向着复杂的分布式架构演变,分布式架构解决了容量、并发等问题,随之而出现的问题就是调用链路的复杂性,问题难以追踪,不能快速准确定位线上问题。

  1. Dapper论文的诞生

谷歌在2010年发布了一篇关于分布式链路调用的论文Dapper(大规模分布式系统链路追踪基础设施),具体论述了在分布式场景下应该如何去定位问题。对系统行为进行跟踪必须是持续进行的,因为异常的发生是无法预料的,而且可能是难以重现的。同时跟踪需要是无所不在,遍布各处的,否则可能会遗漏某些重要的点。基于此Dapper有如下三个最重要的设计目标:

  • 低的额外开销,不过多占用服务器资源
  • 对应用的透明性,可扩展,便于定制化开发
  • 对产生的跟踪数据可以快速分析,实时获取在线服务状态

    Dapper论文原文内容:dapper-2010-1.pdf,译文:链接

  1. OpenTracing规范

基于Dapper中所描述的思路,分布式系统链路追踪的规范OpenTracing由此而生。OpenTracing通过提供平台无关、厂商无关的API,使得开发人员能够方便的添加(或更换)追踪系统的实现。OpenTracing提供了用于运营支撑系统的和针对特定平台的辅助程序库。

  1. 常用APM工具差异对比

基于OpenTracing规范,也诞生了不同厂家实现的APM性能分析工具。APM全称Application Performance Management应用性能管理,目的是通过各种探针采集数据,收集关键指标,同时搭配数据呈现以实现对应用程序性能管理和故障管理的系统化解决方案。下面列举常见的APM工具极其特点:

APM 特点 实现
Zipkin 由Twitter公司开发并开源,Java语言实现,侵入性相对于CAT要低一点,需要对web.xml之类的配置文件做修改,但依然对代码有侵入 代码侵入
Pinpoint 一个韩国团队开源的产品,运用了字节码增强技术,只需要在启动时添加启动参数即可,对代码无侵入,目前支持Java和PHP语言,底层采用HBase来存储数据,探针收集的数据粒度非常细,但性能损耗大 探针,无侵入
CAT 美团开源,基于Java语言开发,目前提供Java、C/C++、Node.js、Python、Go等语言的客户端,监控数据会全量统计,需要在应用程序中埋点,对代码侵入性强 代码侵入
SkyWalking 华为开源产品,现已成为Apache顶级项目,支持Java、.Net、NodeJs等探针,数据存储支持MySQL、Elasticsearch等,采用字节码注入的方式实现,代码的无侵入,探针采集数据粒度粗,性能表现优秀,对云原生支持,增长势头强劲,社区活跃 探针,无侵入

本文主要针对SkyWalking的使用做简单介绍。

架构简介

借用一张官网的图片,SkyWalking的整体架构如图所示:
image.png
整个架构图分为如下几个部分:

  • Agent :负责从应用中,收集链路信息,发送给 SkyWalking OAP 服务器。目前支持 SkyWalking、Zikpin、Jaeger 等提供的 Tracing 数据信息。而我们目前采用的是,SkyWalking Agent 收集 SkyWalking Tracing 数据,传递给服务器。
  • SkyWalking OAP :负责接收 Agent 发送的 Tracing 数据信息,然后进行分析(Analysis Core) ,存储到外部存储器( Storage ),最终提供查询( Query )功能。
  • Storage :Tracing 数据存储。目前支持 ES、MySQL、Sharding Sphere、TiDB、H2 多种存储器。而我们目前采用的是 ES ,主要考虑是 SkyWalking 开发团队自己的生产环境采用 ES 为主。
  • SkyWalking UI :负责提供控台,查看链路等等。

此外SkyWalking的功能是多元化的,一站式的APM工具,已经应用在越来越多地方和场景,包括云原生,此外还可以接入预警提示等功能。
image.png

  • 跟踪、指标和日志记录 SkyWalking旨在实现一致的可观察性。在浏览器中监视应用程序发生的所有事情。
  • 堆栈的代理 Java、.Net Core、PHP、NodeJS、Golang、LUA、Rust 和 C++代理,并进行了积极的开发和维护。
  • 服务网格就绪 内置服务网格可观察性。从 Istio + Envoy Service Mesh 收集和分析数据。

SkyWalking的整体特点总结如下:

  • 多种监控手段,多语言探针支持,Java、Python、.Net Core、NodeJS、Lua等
  • 轻量高效不需要大数据,可以基于MySQL或者Elasticsearch存储
  • 模块化、可视化界面,支持单机以及集群等部署方式
  • 支持多种预警方式,邮件、短信、webhook等

    基本使用

    服务端

    SkyWalking官网提供了多种支持方式,这里主要使用docker进行服务端的环境搭建。由于SkyWalking需要用到多个组件,因此使用docker-compose来进行环境搭建。主要用到组件的版本如下:

  • 操作系统:Ubuntu 20.04LTS

  • docker : 19.03
  • docker-compose: 1.29.2
  • SkyWalking: 8.9.1

    有关docker-compose的参数命令可以查阅:https://docs.docker.com/compose/compose-file/compose-file-v3/

创建相关文件夹

  1. mkdir -p /opt/docker/skywalking

在SkyWalking目录下创建文件docker-compose.yml,文件内容如下:

  1. version: '3.8'
  2. services:
  3. elasticsearch:
  4. image: elasticsearch:7.8.0
  5. container_name: elasticsearch
  6. ports:
  7. - "9200:9200"
  8. healthcheck:
  9. test: [ "CMD-SHELL", "curl --silent --fail localhost:9200/_cluster/health || exit 1" ]
  10. interval: 30s
  11. timeout: 10s
  12. retries: 3
  13. start_period: 10s
  14. environment:
  15. - discovery.type=single-node
  16. - bootstrap.memory_lock=true
  17. - "ES_JAVA_OPTS=-Xms512m -Xmx512m"
  18. ulimits:
  19. memlock:
  20. soft: -1
  21. hard: -1
  22. volumes:
  23. - ./elasticsearch/config/:/usr/share/elasticsearch/config/
  24. networks:
  25. - oap-es
  26. oap:
  27. image: apache/skywalking-oap-server:8.9.1
  28. container_name: oap
  29. depends_on:
  30. elasticsearch:
  31. condition: service_healthy
  32. healthcheck:
  33. test: [ "CMD-SHELL", "/skywalking/bin/swctl ch" ]
  34. interval: 30s
  35. timeout: 10s
  36. retries: 3
  37. start_period: 10s
  38. networks:
  39. - oap-es
  40. - oap-ui
  41. ports:
  42. - "11800:11800"
  43. - "12800:12800"
  44. volumes:
  45. - ./oap/config/alarm-settings.yml:/skywalking/config/alarm-settings.yml
  46. environment:
  47. SW_STORAGE: elasticsearch
  48. SW_STORAGE_ES_CLUSTER_NODES: elasticsearch:9200
  49. SW_HEALTH_CHECKER: default
  50. SW_TELEMETRY: prometheus
  51. JAVA_OPTS: "-Xms1024m -Xmx1024m"
  52. ui:
  53. image: apache/skywalking-ui:8.9.1
  54. container_name: ui
  55. depends_on:
  56. - oap
  57. ports:
  58. - "39043:8080"
  59. deploy:
  60. resources:
  61. limits:
  62. cpus: '0.50'
  63. memory: 256M
  64. volumes:
  65. - ./ui/webapp.yml:/skywalking/webapp/webapp.yml
  66. environment:
  67. SW_OAP_ADDRESS: http://oap:12800
  68. networks:
  69. - oap-ui
  70. networks:
  71. oap-es:
  72. oap-ui:

配置附件:skywalking.zip
需要注意:docker-compose.yml中用到的命令是否支持,可以查阅上面的链接,注意version版本号,此处需要注意的是SkyWalking的启动需要等待Elasticsearch完全启动,因此使用了3.x以上版本支持的healthcheck来保证顺序启动,depends_on本身并不能保证docker容器按照顺序启动,为了避免容器资源占用过多,也可以使用deploy来限制CPU和内存的占用。
关于SkyWalking和Elasticsearch版本选择说明

Since 8.8.0, the image could work with different storage, including ElasticSearch 6/7 and OpenSearch. Before 8.8.0(<= 8.7.0), -es6 image can only connect to Elasticsearch 6 when set SW_STORAGE=elasticsearch. You need to use -es7 image when set SW_STORAGE=elasticsearch7.

一般来说直接执行命令就能启动成功

  1. starsray@starsray:/opt/docker/skywalking$ docker-compose up -d
  2. WARNING: The following deploy sub-keys are not supported and have been ignored: resources.reservations.cpus
  3. Creating network "skywalking_oap-es" with the default driver
  4. Creating network "skywalking_oap-ui" with the default driver
  5. Creating elasticsearch ... done
  6. Creating oap ... done
  7. Creating ui ... done

访问地址:http://localhost:39043,服务端启动成功。
image.png

客户端

SkyWalking使用了基于探针的无侵入方式代理客户端请求,这里使用Java项目来演示客户端接入的方式,首先下载Java客户端代理包:

下载后的目录解压打开,包含以下文件内容,可以看到有很多插件

  1. +-- agent
  2. +-- activations
  3. apm-toolkit-log4j-1.x-activation.jar
  4. apm-toolkit-log4j-2.x-activation.jar
  5. apm-toolkit-logback-1.x-activation.jar
  6. ...
  7. +-- config
  8. agent.config
  9. +-- plugins
  10. apm-dubbo-plugin.jar
  11. apm-feign-default-http-9.x.jar
  12. apm-httpClient-4.x-plugin.jar
  13. .....
  14. +-- optional-plugins
  15. apm-gson-2.x-plugin.jar
  16. .....
  17. +-- bootstrap-plugins
  18. jdk-http-plugin.jar
  19. .....
  20. +-- logs
  21. skywalking-agent.jar
  • 如果插件在所在目录被检测到就会被应用,如果不需要应用直接移除对应的插件即可
  • 日志输出的目录在logs目录中

在项目启动时配置以下参数:

  1. -javaagent:/opt/develop/javaagent/skywalking-agent.jar
  2. -Dskywalking.agent.service_name=skywalking-client
  3. -Dskywalking.collector.backend_service=127.0.0.1:11800
  • javaagent 项目启动时所需要加载的agent包路径,具体路径根据实际情况而定
  • service_name 注册到服务端的客户端名称
  • backend_service SkyWalking服务端地址

需要注意的是:使用SkyWalking8.9.0版本启动时,如果只拷贝了SkyWalking-agent.jar到相应的目录,启动时会报如下错误,但是并不影响使用:

  1. DEBUG 2022-03-27 16:57:58:271 main AgentPackagePath : The beacon class location is jar:file:/opt/develop/javaagent/skywalking-agent.jar!/org/apache/skywalking/apm/agent/core/boot/AgentPackagePath.class.
  2. ERROR 2022-03-27 16:57:58:276 main SnifferConfigInitializer : Failed to read the config file, skywalking is going to run in default config.
  3. org.apache.skywalking.apm.agent.core.conf.ConfigNotFoundException: Failed to load agent.config.
  4. at org.apache.skywalking.apm.agent.core.conf.SnifferConfigInitializer.loadConfig(SnifferConfigInitializer.java:213)
  5. at org.apache.skywalking.apm.agent.core.conf.SnifferConfigInitializer.initializeCoreConfig(SnifferConfigInitializer.java:65)
  6. ...

不能加载到agent配置文件夹,所以在拷贝agent的时候,直接将整个文件夹拷贝过去就好了,而且里面包含了很多可选择插件。
更多关于客户端接入的注意事项或者对于插件的选择扩展,查看官方文档提供的建议: