Skywalking入门

Posted by Kaka Blog on September 5, 2023

Skywalking简介

skywalking是一个优秀的国产开源框架,2015年由个人吴晟(华为开发者)开源 , 2017年加入Apache孵化器。短短两年就被Apache收入麾下,实力可见一斑。 skywalking支持dubbo,SpringCloud,SpringBoot集成,代码无侵入,通信方式采用GRPC,性能较好,实现方式是java探针,支持告警,支持JVM监控,支持全局调用统计等等,功能较完善。

Skywalking架构

SkyWalking 逻辑上分为四部分: 探针, 平台后端, 存储和用户界面。

  • 探针 基于不同的来源可能是不一样的, 但作用都是收集数据, 将数据格式化为 SkyWalking 适用的格式.
  • 平台后端 支持数据聚合, 数据分析以及驱动数据流从探针到用户界面的流程。分析包括 Skywalking 原生追踪和性能指标以及第三方来源,包括 Istio 及 Envoy telemetry , Zipkin 追踪格式化等。
  • 存储 通过开放的插件化的接口存放 SkyWalking 数据. 你可以选择一个既有的存储系统, 如 ElasticSearch, H2 或 MySQL 集群(Sharding-Sphere 管理),也可以选择自己实现一个存储系统. 当然, 我们非常欢迎你贡献新的存储系统实现。
  • UI 一个基于接口高度定制化的Web系统,用户可以可视化查看和管理 SkyWalking 数据。

部署安装

1、采用docker-compose部署,存储使用的是es7,同时将oap注册到了nacos。nacos部署见之前的文章,启动nacos后需要新建命名空间dev。新建docker-compose.yml文件,文件内容如下:

version: '2'
services:
  elasticsearch:
    image: elasticsearch:7.14.2
    container_name: elasticsearch
    restart: always
    ports:
      - 9200:9200
    environment:
      - "TAKE_FILE_OWNERSHIP=true" # volumes 挂载权限 如果不想要挂载es文件改配置可以删除
      - "discovery.type=single-node" #单机模式启动
      - "TZ=Asia/Shanghai" # 设置时区
      - "ES_JAVA_OPTS=-Xms512m -Xmx512m" # 设置jvm内存大小
    volumes:
      - /data/skywalking/elasticsearch/logs:/usr/share/elasticsearch/logs
      - /data/skywalking/elasticsearch/data:/usr/share/elasticsearch/data
    ulimits:
      memlock:
        soft: -1
        hard: -1
  skywalking-oap-server:
    image: apache/skywalking-oap-server:8.9.1
    container_name: skywalking-oap-server
    depends_on:
      - elasticsearch
    links:
      - elasticsearch
    restart: always
    ports:
      - 11800:11800
      - 12800:12800
    environment:
	#此处的参数为容器里/skywalking/config/application.yml的配置
      SW_STORAGE: elasticsearch  # 指定ES版本
      SW_STORAGE_ES_CLUSTER_NODES: elasticsearch:9200
      SW_CLUSTER: nacos
      SW_SERVICE_NAME: skywalking-oap-server
      SW_CLUSTER_NACOS_HOST_PORT: 192.168.10.236:8848
      SW_CLUSTER_NACOS_NAMESPACE: dev
      TZ: Asia/Shanghai
  skywalking-ui:
    image: apache/skywalking-ui:8.9.1
    container_name: skywalking-ui
    depends_on:
      - skywalking-oap-server
    links:
      - skywalking-oap-server
    restart: always
    ports:
      - 8080:8080
    environment:
      SW_OAP_ADDRESS: http://skywalking-oap-server:12800
      TZ: Asia/Shanghai

2、在docker-compose.yml文件当前目录下打开命令行,运行命令:

docker-compose up

正常情况下可以通过http://localhost:8080访问UI界面。

UI界面说明

  • 仪表盘:查看被监控服务的运行状态
  • 拓扑图:以拓扑图的方式展现服务直接的关系,并以此为入口查看相关信息
  • 追踪:以接口列表的方式展现,追踪接口内部调用过程
  • 性能剖析:单独端点进行采样分析,并可查看堆栈信息
  • 日志
  • 告警:触发告警的告警列表,包括实例,请求超时等。
  • 事件
  • 调试

测试

下载探针

​ https://archive.apache.org/dist/skywalking/java-agent/

​ 根据Skywalking版本进行下载,这里下载的是8.9.0版本。

IDEA使用探针

这里使用的是上一篇minio的工程,配置VM options:

-javaagent:D:\Download\skywalking-agent\skywalking-agent.jar -Dskywalking.agent.service_name=minio-demo-service -Dskywalking.collector.backend_service=192.168.10.27:11800 

参数说明:

  • javaagent:探针jar包位置
  • -Dskywalking.agent.service_name:在Skywalking中的服务名称,默认值为Your_ApplicationName
  • -Dskywalking.collector.backend_service:skywalking-oap-server地址,默认值为127.0.0.1:11800

启动程序,调用接口,刷新下Skywalking的时间范围,可以看到Skywalking里面已经有数据。

日志对接

在skywalking的UI端有一个日志的模块,用于收集客户端的日志,默认是没有数据的,那么需要如何将日志数据传输到skywalking中呢?

日志框架的种类很多,比较出名的有log4j,logback,log4j2,以springboot默认的logback为例子介绍一下如何配置,官方文档如下:

  • log4j:java-agent/application-toolkit-log4j-1.x/
  • log4j2:java-agent/application-toolkit-log4j-2.x/
  • logback:java-agent/application-toolkit-logback-1.x/

1、添加依赖

根据官方文档,需要先添加依赖,如下:

<dependency>
   <groupId>org.apache.skywalking</groupId>
   <artifactId>apm-toolkit-logback-1.x</artifactId>
   <version>8.10.0</version>
</dependency>

2、添加配置文件

新建一个logback-spring.xml放在resource目录下,配置如下:

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod=" 5 seconds">
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.mdc.TraceIdMDCPatternLogbackLayout">
                <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{tid}] [%thread] %-5level %logger{36} -%msg%n</Pattern>
            </layout>
        </encoder>
    </appender>

    <appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
        <discardingThreshold>0</discardingThreshold>
        <queueSize>1024</queueSize>
        <neverBlock>true</neverBlock>
        <appender-ref ref="STDOUT"/>
    </appender>


    <appender name="grpc-log" class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.log.GRPCLogClientAppender">
        <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="org.apache.skywalking.apm.toolkit.log.logback.v1.x.mdc.TraceIdMDCPatternLogbackLayout">
                <Pattern>%d{yyyy-MM-dd HH:mm:ss.SSS} [%X{tid}] [%thread] %-5level %logger{36} -%msg%n</Pattern>
            </layout>
        </encoder>
    </appender>

    <root level="INFO">
        <appender-ref ref="grpc-log" />
        <appender-ref ref="ASYNC"/>
    </root>
</configuration>

3、启动程序

会发现Skywalking里已经有了日志,与idea控制台的日志一致。

docker使用探针

其实原理都一样,配置探针包的地址、配置skywalking服务端地址、配置服务名称。

​ 有几种方式:

​ 1、将外部的agent包,挂载到docker容器中,然后指定vm参数

​ 2、构建docker时,把agent包打进docker镜像里,dockerfile修改enrtypoint,添加-javaagent参数

​ 3、将agent包打到基础镜像里,dockerfile直接引用这个基础镜像

什么是探针

在JVM中运行中,类是通过classLoader加载.class文件进行生成的。在类加载器加载.class文件生成对应的类对象之前时,我们可以通过修改.class文件内容(就是字节码修改技术),达到修改类的目的。JDK提供了对字节码进行操作的一系列api,而使用这些api开发出的程序就可以称之为java agent。探针说白了,就是在应用启动之前,比你的应用 main 方法更早启动的一个系统,它可以对你的系统的类进行拦截,你可以将它类比为一个更强大的 AOP 工具。

参考资料