基于Apache SkyWalking构建企业级APM(Application Performance Monitoring)监控系统

本文涉及的产品
应用实时监控服务-应用监控,每月50GB免费额度
日志服务 SLS,月写入数据量 50GB 1个月
应用实时监控服务-用户体验监控,每月100OCU免费额度
简介: 基于Apache SkyWalking构建企业级APM(Application Performance Monitoring)监控系统

正文


一、什么是SkyWalking


SkyWalking是一个开源的观测平台,用于从服务和云原生等基础设施中收集、分析、聚合以及可视化数据。SkyWalking 提供了一种简便的方式来清晰地观测分布式系统。相比较zipkin而言,skywalking利用agent字节码增强技术实现代码无侵入,通信方式采用GRPC,性能较好,实现方式是java探针,支持告警,支持JVM监控,支持全局调用统计,UI界面更加强大等优点。


二、SkyWalking的搭建


222.png


skywalking使用Agent代理技术,相当于JVM层面的AOP 技术,在执行我们项目的时候,skywalking经过代理,然后收集我们的系统数据,然后经过可视化界面展示。


安装skywalking


从8.8.0开始,Java Agent从原始的主存储库中分离出来。所以我们需要下载两个文件


Apache Downloads 主程序

Apache Downloads agent代理


在apache-skywalking-apm-9.0.0\apache-skywalking-apm-bin\bin路径下启动,在webapp中的webapp.yml中可以修改启动端口,默认是8080


111.png


然后访问 ip:8080


agent模块解压后有skywalking-agent.jar


770259d1a417490293a94d9fc2494375.png


三、整合springboot


1、整合skywalking


由于skywalking是无代码侵入式的,启动项目时需要配置jvm参数


#skywalking-agent.jar的路径
-javaagent:E:\java-tools\skywalking\skywalking-agent\skywalking-agent.jar
#启动服务的名称
-Dskywalking.agent.service_name=xiaojie-sso
#连接到skywalking的地址
-Dskywalking.collector.backend_service=127.0.0.1:11800


2、初识skywalking界面


770259d1a417490293a94d9fc2494375.png

 

8074245061964fd5a3b4850740109991.png


安装好之后可以随意点点,提供了CPU、JVM、垃圾回收,数据库、线程池、日志、拓扑图等等很多信息。


3、上报日志


maven依赖


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


logback.yml


<?xml version="1.0" encoding="utf-8" ?>
        <!---scan这个属性是用来查看配置信息的,scanPeriod的值是固定多长时间扫描一次,周期内新生成的文件会覆盖旧文件-->
<configuration>
    <property name="LOG_FILE_LOCATION" value="./log/"/>
    <property name="CONSOLE_LOG_PATTERN"
              value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %highlight(%-5level) %cyan(%logger{50}) - %highlight(%msg) %n"/>
    <property name="FILE_LOG_PATTERN"
              value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{50} - %msg%n"/>
    <appender name="consoleLog" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
        </layout>
    </appender>
    <appender name="fileInfoLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>ERROR</level>
            <!--匹配就舍去-->
            <onMatch>DENY</onMatch>
            <onMismatch>ACCEPT</onMismatch>
        </filter>
        <file>${LOG_FILE_LOCATION}/info.log</file>
        <encoder>
            <pattern>
                ${FILE_LOG_PATTERN}
            </pattern>
        </encoder>
        <!--滚动策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!--日志文件输出的文件名-->
            <FileNamePattern>${LOG_FILE_LOCATION}/bak/info.%d{yyyy-MM-dd}.%i.log.gz</FileNamePattern>
            <!--日志文件保留天数-->
            <MaxHistory>30</MaxHistory>
            <MaxFileSize>10MB</MaxFileSize>
        </rollingPolicy>
    </appender>
    <appender name="fileErrorLog" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>ERROR</level>
        </filter>
        <file>${LOG_FILE_LOCATION}/error.log</file>
        <encoder>
            <pattern>
                <pattern>${FILE_LOG_PATTERN}
                </pattern>
            </pattern>
        </encoder>
        <!--滚动策略-->
        <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
            <!--日志文件输出的文件名-->
            <FileNamePattern>${LOG_FILE_LOCATION}/bak/error.%d{yyyy-MM-dd}.%i.log.gz</FileNamePattern>
            <!--日志文件保留天数-->
            <MaxHistory>30</MaxHistory>
            <MaxFileSize>10MB</MaxFileSize>
        </rollingPolicy>
    </appender>
    <!--打印tranceid-->
    <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"/>
        <appender-ref ref="consoleLog"/>
        <appender-ref ref="fileInfoLog"/>
        <appender-ref ref="fileErrorLog"/>
    </root>
</configuration>


4、持久化配置


修改apache-skywalking-apm-9.0.0\apache-skywalking-apm-bin\config路径下的application.yml


第一处、修改storage为mysql,我这里以mysql为例,支持多种修改


333.png


第二处、修改mysql的连接


444.png


需要手动在数据库创建swtest的数据库,然后启动skywalking,表自动创建。


四、报警系统


770259d1a417490293a94d9fc2494375.png


apache-skywalking-apm-9.0.0\apache-skywalking-apm-bin\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
    #过去3分钟内服务平均响应时间超过1秒
    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
    #服务成功率在过去2分钟内低于80%
    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
    #再过去的3分钟内有超过50%,75%,90%,95%,99%响应时间大于1000毫秒
    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
    #最近2分钟内服务实例的平均响应时间超过1秒 
    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
    #最近2分钟内数据库的平均响应时间超过1秒 
    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
    #端点平均响应时间过去2分钟超过1秒,断点可以理解为某个路径
    message: Response time of endpoint relation {name} is more than 1000ms in 2 minutes of last 10 minutes
#  Active endpoint related metrics alarm will cost more memory than service and service instance metrics alarm.
#  Because the number of endpoint is much more than service and instance.
#
#  endpoint_resp_time_rule:
#    metrics-name: endpoint_resp_time
#    op: ">"
#    threshold: 1000
#    period: 10
#    count: 2
#    silence-period: 5
#    message: Response time of endpoint {name} is more than 1000ms in 2 minutes of last 10 minutes
webhooks:
  - http://127.0.0.1:8090/notify/ #告警路径,需要我们自定义接口实现,post接口
#  - http://127.0.0.1/go-wechat/


属性参照如下


111.png


定义告警实体类


@Data
public class AlarmMessageDto {
    private String scopeId;
    private String name;
    private String id0;
    private String id1;
    private String alarmMessage;
    private long startTime;
}


定义接口


  @Override
    public void send(List<AlarmMessageDto> alarmMessageList) {
        //实际生产中应当单独建立一个监控系统的服务,使用mq 发送短信,邮件或者微信公众号模板方式解决,此处只是演示
        for (AlarmMessageDto alarm: alarmMessageList) {
            log.info("报警信息为>>>>>>>>{}",alarm.getAlarmMessage());
        }
    }


完整代码参考 spring-boot: Springboot整合redis、消息中间件等相关代码

相关实践学习
通过云拨测对指定服务器进行Ping/DNS监测
本实验将通过云拨测对指定服务器进行Ping/DNS监测,评估网站服务质量和用户体验。
相关文章
|
2月前
|
移动开发 监控 Android开发
Android & iOS 使用 ARMS 用户体验监控(RUM)的最佳实践
本文主要介绍了 ARMS 用户体验监控的基本功能特性,并介绍了在几种常见场景下的最佳实践。
258 11
|
1月前
|
消息中间件 安全 Kafka
Apache Kafka安全加固指南:保护你的消息传递系统
【10月更文挑战第24天】在现代企业环境中,数据的安全性和隐私保护至关重要。Apache Kafka作为一款广泛使用的分布式流处理平台,其安全性直接影响着业务的稳定性和用户数据的安全。作为一名资深的Kafka使用者,我深知加强Kafka安全性的重要性。本文将从个人角度出发,分享我在实践中积累的经验,帮助读者了解如何有效地保护Kafka消息传递系统的安全性。
58 7
|
1月前
|
消息中间件 数据挖掘 Kafka
Apache Kafka流处理实战:构建实时数据分析应用
【10月更文挑战第24天】在当今这个数据爆炸的时代,能够快速准确地处理实时数据变得尤为重要。无论是金融交易监控、网络行为分析还是物联网设备的数据收集,实时数据处理技术都是不可或缺的一部分。Apache Kafka作为一款高性能的消息队列系统,不仅支持传统的消息传递模式,还提供了强大的流处理能力,能够帮助开发者构建高效、可扩展的实时数据分析应用。
75 5
|
1月前
|
消息中间件 存储 监控
构建高可用性Apache Kafka集群:从理论到实践
【10月更文挑战第24天】随着大数据时代的到来,数据传输与处理的需求日益增长。Apache Kafka作为一个高性能的消息队列服务,因其出色的吞吐量、可扩展性和容错能力而受到广泛欢迎。然而,在构建大规模生产环境下的Kafka集群时,保证其高可用性是至关重要的。本文将从个人实践经验出发,详细介绍如何构建一个高可用性的Kafka集群,包括集群规划、节点配置以及故障恢复机制等方面。
67 4
|
2月前
|
消息中间件 分布式计算 大数据
大数据-166 Apache Kylin Cube 流式构建 整体流程详细记录
大数据-166 Apache Kylin Cube 流式构建 整体流程详细记录
68 5
|
2月前
|
存储 SQL 分布式计算
大数据-162 Apache Kylin 全量增量Cube的构建 Segment 超详细记录 多图
大数据-162 Apache Kylin 全量增量Cube的构建 Segment 超详细记录 多图
58 3
|
29天前
|
存储 数据挖掘 数据处理
巴别时代使用 Apache Paimon 构建 Streaming Lakehouse 的实践
随着数据湖技术的发展,企业纷纷探索其优化潜力。本文分享了巴别时代使用 Apache Paimon 构建 Streaming Lakehouse 的实践。Paimon 支持流式和批处理,提供高性能、统一的数据访问和流批一体的优势。通过示例代码和实践经验,展示了如何高效处理实时数据,解决了数据一致性和故障恢复等挑战。
110 61
|
1月前
|
消息中间件 Java Kafka
初识Apache Kafka:搭建你的第一个消息队列系统
【10月更文挑战第24天】在数字化转型的浪潮中,数据成为了企业决策的关键因素之一。而高效的数据处理能力,则成为了企业在竞争中脱颖而出的重要武器。在这个背景下,消息队列作为连接不同系统和服务的桥梁,其重要性日益凸显。Apache Kafka 是一款开源的消息队列系统,以其高吞吐量、可扩展性和持久性等特点受到了广泛欢迎。作为一名技术爱好者,我对 Apache Kafka 产生了浓厚的兴趣,并决定亲手搭建一套属于自己的消息队列系统。
50 2
初识Apache Kafka:搭建你的第一个消息队列系统
|
2月前
|
Java 大数据 数据库连接
大数据-163 Apache Kylin 全量增量Cube的构建 手动触发合并 JDBC 操作 Scala
大数据-163 Apache Kylin 全量增量Cube的构建 手动触发合并 JDBC 操作 Scala
31 2
大数据-163 Apache Kylin 全量增量Cube的构建 手动触发合并 JDBC 操作 Scala
|
2月前
|
SQL 分布式计算 大数据
大数据-160 Apache Kylin 构建Cube 按照日期构建Cube 详细记录
大数据-160 Apache Kylin 构建Cube 按照日期构建Cube 详细记录
43 2

推荐镜像

更多