APM概述

APM (Application Performance Management) 即应用性能管理系统,是对企业系统即时监控以实现
对应用程序性能管理和故障管理的系统化的解决方案。应用性能管理,主要指对企业的关键业务应用进
行监测、优化,提高企业应用的可靠性和质量,保证用户得到良好的服务,降低IT总拥有成本。
APM系统是可以帮助理解系统行为、用于分析性能问题的工具,以便发生故障的时候,能够快速定位和
解决问题。
随着分布式系统和微服务架构的出现,一次用户的请求会经过多个系统,不同服务之间的调用关系十分
复杂,任何一个系统出错都可能影响整个请求的处理结果。以往的监控系统往往只能知道单个系统的健
康状况、一次请求的成功失败,无法快速定位失败的根本原因。
除此之外,复杂的分布式系统也面临这下面这些问题:

  • 性能分析:一个服务依赖很多服务,被依赖的服务也依赖了其他服务。如果某个接口耗时突然变长
    了,那未必是直接调用的下游服务慢了,也可能是下游的下游慢了造成的,如何快速定位耗时变长
    的根本原因呢?
  • 链路梳理:需求迭代很快,系统之间调用关系变化频繁,靠人工很难梳理清楚系统链路拓扑(系统
    之间的调用关系)。
    为了解决这些问题,Google 推出了一个分布式链路跟踪系统 Dapper ,之后各个互联网公司都参照
    Dapper 的思想推出了自己的分布式链路跟踪系统,而这些系统就是分布式系统下的APM系统。Skywalking就是其中的优秀代表。

开源产品对比

PinPoint

Pinpoint是由一个韩国团队实现并开源,针对Java编写的大规模分布式系统设计,通过JavaAgent的机
制做字节代码植入,实现加入traceid和获取性能数据的目的,对应用代码零侵入。
官网

SkyWalking

SkyWalking是apache基金会下面的一个开源APM项目,为微服务架构和云原生架构系统设计。它通过
探针自动收集所需的指标,并进行分布式追踪。通过这些调用链路以及指标,Skywalking APM会感知
应用间关系和服务间关系,并进行相应的指标统计。Skywalking支持链路追踪和监控应用组件基本涵盖
主流框架和容器,如国产RPC Dubbo和motan等,国际化的spring boot,spring cloud。
官网
中文文档

Zipkin

Zipkin是由Twitter开源,是分布式链路调用监控系统,聚合各业务系统调用延迟数据,达到链路调用监
控跟踪。Zipkin基于Google的Dapper论文实现,主要完成数据的收集、存储、搜索与界面展示。
官方

CAT

CAT是由大众点评开源的项目,基于Java开发的实时应用监控平台,包括实时应用监控,业务监控,可
以提供十几张报表展示。CAT对应用的侵入性比较大,需要编码采集数据。
官网

Skywalking简介

根据官方的解释,Skywalking是一个可观测性分析平台(Observability Analysis Platform简称OAP)
和应用性能管理系统(Application Performance Management简称APM)。
提供分布式链路追踪、服务网格(Service Mesh)遥测分析、度量(Metric)聚合和可视化一体化解决方案。
下面是Skywalking的几大特点:

  • 多语言自动探针,Java,.NET Core和Node.JS。
  • 多种监控手段,语言探针和service mesh。
  • 轻量高效。不需要额外搭建大数据平台。
  • 模块化架构。UI、存储、集群管理多种机制可选。
  • 支持告警。
  • 优秀的可视化效果。
    整体架构
    整体架构包含如下三个组成部分:
  1. 探针(agent)负责进行数据的收集,包含了Tracing和Metrics的数据,agent会被安装到服务所在的
    服务器上,以方便数据的获取。
  2. 可观测性分析平台OAP(Observability Analysis Platform),接收探针发送的数据,并在内存中使
    用分析引擎(Analysis Core)进行数据的整合运算,然后将数据存储到对应的存储介质上,比如
    Elasticsearch、MySQL数据库、H2数据库等。同时OAP还使用查询引擎(Query Core)提供HTTP查
    询接口。
  3. Skywalking提供单独的UI进行数据的查看,此时UI会调用OAP提供的接口,获取对应的数据然后
    进行展示。
    Skywalking相比较其他的分布式链路监控工具,具有以下特点:
  • 社区相当活跃。Skywalking已经进入apache孵化,目前的start数已经超过17.9K,最新版本8.7.0已
    经发布。开发者是华为的吴晟,可以直接和项目发起人交流进行问题的解决。
  • Skywalking支持Java,.NET Core和Node.JS语言。相对于其他平台:比如Pinpoint支持Java和
    PHP,具有较大的优势。
  • 探针无倾入性。对比CAT具有倾入性的探针,优势较大。不修改原有项目一行代码就可以进行集
    成。
  • 探针性能优秀。有网友对Pinpoint和Skywalking进行过测试,由于Pinpoint收集的数据过多,所以
    对性能损耗较大,而Skywalking探针性能十分出色。
  • 支持组件较多。特别是对Rpc框架的支持,这是其他框架所不具备的。Skywalking对Dubbo、
    gRpc等有原生的支持,甚至连小众的vertx、motan和sofarpc都支持。
    Skywalking主要概念(6.0开始)包含:
  • 服务(Service) 比如用户服务、订单服务
  • 端点(Endpoint) 比如/user/findById,可以理解为URL
  • 实例(Instance) 一般地都是多个实例一起提供某个服务
  • backend 提供数据收集,分析,存储,查询功能,成为OAP
  • UI UI界面展示

环境搭建

OAP和UI的安装

Skywalking的后端存储支持H2,ElasticSearch,MySQL,PostGre,InfluxDB等,本次选用ElasticSearch。
从官网下载8.7.0,注意,因为es的版本中7和6有比较大的差别,所以根据es要下载对应的版本。
安装文档
下载对应es版本的
解压后在config的application.yaml中配置es的地址
启动bin/startup.sh即可,观察logs下面的日志,其中启动的时候有几个脚本,分别是是否初始化的OAP脚本,webapp的脚本,可以按需启动,也可以简单地启动startup.sh。
启动后,访问http://ip:8080/出现skywalking界面即表示安装成功了。端口可以在webapp/webapp.yaml中修改。

agent的使用

agent探针可以让我们不修改代码的情况下,对java应用上使用到的组件进行动态监控,获取运行数据
发送到OAP上进行统计和存储。agent探针在java中是使用java agent技术实现的,不需要更改任何代
码,java agent会通过虚拟机(VM)接口来在运行期更改代码。
Agent探针支持 JDK 1.6 - 12的版本,Agent探针所有的文件在Skywalking的agent文件夹下。文件目录
如下

+-- agent
    +-- activations
         apm-toolkit-log4j-1.x-activation.jar
         apm-toolkit-log4j-2.x-activation.jar
         apm-toolkit-logback-1.x-activation.jar
         ...
    +-- config
         agent.config  
    +-- plugins
         apm-dubbo-plugin.jar
         apm-feign-default-http-9.x.jar
         apm-httpClient-4.x-plugin.jar
         .....
    +-- optional-plugins
         apm-gson-2.x-plugin.jar
         .....
    +-- bootstrap-plugins
         jdk-http-plugin.jar
         .....
    +-- logs
    skywalking-agent.jar

部分插件在使用上会影响整体的性能或者由于版权问题放置于可选插件包中,不会直接加载,如
果需要使用,将可选插件中的jar包拷贝到plugins包下。如果要去除某个插件就是从plugins目录去除即可。其中对于JDK的,

  1. bootstrap-plugins/apm-jdk-http-plugin-8.7.0.jar迁移到plugins支持JDK的HttpURLConnection
  2. bootstrap-plugins/apm-jdk-threading-plugin-8.7.0.jar迁移到plugins支持JDK的Runnable和Callable,但是不能使用lamda表达式,只能使用其子类或者匿名内部类。并在agent.config中配置plugin.jdkthreading.threading_class_prefixes=xxxx,多个可以用逗号隔开

agent/config/agent.config中必须配置的有agent.service_name代表你的服务,会显示在UI上,agent.backend_service指定OAP的地址,集群的话就多个地址用逗号分隔。
TOMCAT配置agent:
CATALINA_OPTS="$CATALINA_OPTS -javaagent:/path-to-skywalking/apache- skywalking-apm-bin/agent/skywalking-agent.jar"; export CATALINA_OPTS
普通jar包启动的添加-javaagent
参考:agent配置
java探针目前支持的技术
注意-javaagent必须在其他参数之前。

配置覆盖

https://skywalking.apache.org/docs/skywalking-java/latest/en/setup/service-agent/java-agent/setting-override/

配置忽略路径

参考

告警规则配置

在skywalking的配置文件config/alarm-settings.yml中定义告警规则。

rules:
  # Rule unique name, must be ended with `_rule`.
  service_resp_time_rule:
    metrics-name: service_resp_time
    op: ">"
    threshold: 1000
    period: 10
    count: 3
    silence-period: 5
    message: Response time of service {name} is more than 1000ms in 3 minutes of last 10 minutes.
  service_sla_rule:
    # Metrics value need to be long, double or int
    metrics-name: service_sla
    op: "<"
    threshold: 8000
    # The length of time to evaluate the metrics
    period: 10
    # How many times after the metrics match the condition, will trigger alarm
    count: 2
    # How many times of checks, the alarm keeps silence after alarm triggered, default as same as period.
    silence-period: 3
    message: Successful rate of service {name} is lower than 80% in 2 minutes of last 10 minutes
  service_resp_time_percentile_rule:
    # Metrics value need to be long, double or int
    metrics-name: service_percentile
    op: ">"
    threshold: 1000,1000,1000,1000,1000
    period: 10
    count: 3
    silence-period: 5
    message: Percentile response time of service {name} alarm in 3 minutes of last 10 minutes, due to more than one condition of p50 > 1000, p75 > 1000, p90 > 1000, p95 > 1000, p99 > 1000
  service_instance_resp_time_rule:
    metrics-name: service_instance_resp_time
    op: ">"
    threshold: 1000
    period: 10
    count: 2
    silence-period: 5
    message: Response time of service instance {name} is more than 1000ms in 2 minutes of last 10 minutes
  database_access_resp_time_rule:
    metrics-name: database_access_resp_time
    threshold: 1000
    op: ">"
    period: 10
    count: 2
    message: Response time of database access {name} is more than 1000ms in 2 minutes of last 10 minutes
  endpoint_relation_resp_time_rule:
    metrics-name: endpoint_relation_resp_time
    threshold: 1000
    op: ">"
    period: 10
    count: 2
    message: Response time of endpoint relation {name} is more than 1000ms in 2 minutes of last 10 minutes

可以通过配置webhooks:来接收告警推送做自定义处理
详细文档

自定义插件开发

虽然skywalking已经支持绝大部分的中间件或者框架,但免不了也有不支持的,这个时候就需要我们自己来开发插件了。参照插件开发指南
首先下载源码,从8.8.0开始,java agent的源码已经被迁移到独立的仓库了,clone下来后是编译不过的,貌似少了很多源码,可能是代码保护吧。

mvn -N io.takari:maven:wrapper -Dmaven=3.xx
mvnw.cmd clean package -Pall -Dcheckstyle.skip -Dmaven.test.skip=true 

参照其他的插件源码,新建submodule进行开发。
注意,如果用到了新组件需要在skywalking目录下component-libraries.yml中配置component的id和name,不能和其他的一样,比如我开发了基于vertx和Jersey的组件,在文件中注册

  Vertx-Jersey:
    id: 200
    languages: Java

插件可以自定义配置,通过如下的代码

import org.apache.skywalking.apm.agent.core.boot.PluginConfig;
public class VertxHandlerPluginConfig {
    public static class Plugin {
        @PluginConfig(root = VertxHandlerPluginConfig.class)
        public static class VertxHandler {
            public static String HANDLER_CLASS_PREFIXES = "";
        }
    }
}

然后在agent/config/agent.config中通过plugin.vertxhandler.handler_class_prefixes=xxx配置

日志集成

skywalking可以和主流的日志框架进行集成,文档参考

compile group: 'org.apache.skywalking', name: 'apm-toolkit-logback-1.x', version: '8.7.0'
    //compile group: 'org.apache.skywalking', name: 'apm-toolkit-trace', version: '8.7.0'
	
<!-- skywalking grpc 日志收集 8.4.0版本开始支持 -->
<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}  [%thread] %-5level %logger{36} -%msg%n</pattern>-->
			<!--格式化输出:%d表示日期,%thread表示线程名,%-5level:级别从左显示5个字符宽度%msg:日志消息,%n是换行符-->
			<pattern>%contextName: %X{METHOD-INVOKE-KEY}  [%X{tid}] %d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} %replace(%caller{1}){'(Caller(.+?)(?=\())|\r|\n|\s*|\t', ''} - %msg%n</pattern>
		</layout>
	</encoder>
</appender>
<appender-ref ref="grpc-log"/>
<!-- 配置异步记录 AsyncAppender -->
<appender name="ASYNC" class="ch.qos.logback.classic.AsyncAppender">
	<discardingThreshold>0</discardingThreshold>
	<queueSize>1024</queueSize>
	<neverBlock>true</neverBlock>
	<appender-ref ref="grpc-log"/>
</appender>
~~在agent/config/agent.config增加以下配置	
plugin.toolkit.log.grpc.reporter.server_host=${SW_GRPC_LOG_SERVER_HOST:xxip}
plugin.toolkit.log.grpc.reporter.server_port=${SW_GRPC_LOG_SERVER_PORT:11800}
plugin.toolkit.log.grpc.reporter.max_message_size=${SW_GRPC_LOG_MAX_MESSAGE_SIZE:10485760}
plugin.toolkit.log.grpc.reporter.upstream_timeout=${SW_GRPC_LOG_GRPC_UPSTREAM_TIMEOUT:30}~~ 
Logo

为开发者提供学习成长、分享交流、生态实践、资源工具等服务,帮助开发者快速成长。

更多推荐