关于java:Skywalking应用实战-Agent探针Rocketbot以及告警

69次阅读

共计 12630 个字符,预计需要花费 32 分钟才能阅读完成。

3 Skywalking 利用

相干术语:

skywalking-collector: 链路数据归集器,数据能够落地 ElasticSearch/H2
skywalking-ui:web 可视化平台,用来展现落地的数据
skywalking-agent: 探针,用来收集和发送数据到归集器

3.1 agent 下载

Skywalking-agent,它简称探针,用来收集和发送数据到归集器,咱们先来学习下探针应用,探针对应的 jar 包在 Skywalking 源码中,咱们须要先下载源码。

Skywalking 源码下载地址:https://archive.apache.org/di…,咱们以后应用的版本是8.3.0,抉择下载对应版本。

agent 目录构造如下:

agent
    ├── activations
    │   ├── apm-toolkit-kafka-activation-8.3.0.jar
    │   ├── ...
    │   └── apm-toolkit-trace-activation-8.3.0.jar
    ├── config # Agent 配置文件
    │   └── agent.config
    ├── logs # 日志文件
    ├── optional-plugins # 可选插件
    │   ├── apm-customize-enhance-plugin-8.3.0.jar
    │   ├── apm-gson-2.x-plugin-8.3.0.jar
    │   └── ... ...
    ├── bootstrap-plugins # jdk 插件
    │   ├── apm-jdk-http-plugin-8.3.0.jar
    │   └── apm-jdk-threading-plugin-8.3.0.jar
    ├── plugins # 以后失效插件
    │   ├── apm-activemq-5.x-plugin-8.3.0.jar
    │   ├── apm-armeria-0.84.x-plugin-8.3.0.jar
    │   ├── apm-armeria-0.85.x-plugin-8.3.0.jar
    │   └── ... ...
    ├── optional-reporter-plugins
    │   └── kafka-reporter-plugin-8.3.0.jar
    └── skywalking-agent.jar【利用的 jar 包】

目录构造阐明:

activations 以后 skywalking 正在应用的性能组件。agent.config 文件是 SkyWalking Agent 的惟一配置文件。plugins 目录存储了以后 Agent 失效的插件。optional-plugins 目录存储了一些可选的插件(这些插件可能会影响整个零碎的性能或是有版权问题),如果须要应用这些插件,需将相应 jar 包挪动到 plugins 目录下。skywalking-agent.jar 是 Agent 的外围 jar 包,由它负责读取 agent.config 配置文件,加载上述插件 jar 包,运行时收集到 的 Trace 和 Metrics 数据也是由它发送到 OAP 集群的。

咱们在应用 Skywalking 的时候,整个过程中都会用到skywalking-agent.jar,而无论是 RPC 还是 HTTP 开发的我的项目,用法都一样,因而咱们解说以后支流的 SpringBoot 我的项目对 agent 的应用即可。

3.2 agent 利用

我的项目应用 agent,如果是开发环境,能够应用 IDEA 集成,如果是生产环境,须要将我的项目打包上传到服务器。为了应用 agent,咱们同时须要将下载的 apache-skywalking-apm-bin 文件包上传到服务器下来。不过无论是开发环境还是生产环境应用 agent,对我的项目都是无侵入式的。

3.2.1 利用名配置

咱们须要用到 agent,此时须要将agent/config/agent.config 配置文件拷贝到每个须要集成 Skywalking 工程的 resource 目录下,咱们将 agent.config 拷贝到 工程 \hailtaxi-parent的每个子工程目录下,并批改其中的 agent.service_name,批改如下:

hailtaxi-gateway:    agent.service_name=${SW_AGENT_NAME:hailtaxi-gateway}
hailtaxi-driver:    agent.service_name=${SW_AGENT_NAME:hailtaxi-driver}
hailtaxi-order:        agent.service_name=${SW_AGENT_NAME:hailtaxi-order}

agent.config 是一个 KV 构造的配置文件,相似于 properties 文件,value 局部应用 “${}” 包裹,其中应用冒号 (":") 分为两局部,前半部分是能够笼罩该配置项的零碎环境变量名称,后半部分为默认值。例如这里的 agent.service_name 配置项,如果零碎环境变量中指定了 SW_AGENT_NAME 值(留神,全是大写),则优先应用环境变量中指定的值,如果环境变量未指定,则应用 hailtaxi-driver 这个默认值。

间接把配置批改好后放到我的项目的 resource 目录下 (或者其余门路) 是最不容易才出错的一种形式,同时咱们能够采纳其余形式笼罩默认值:

1)JVM 笼罩配置

例如这里的 agent.service_name 配置项,如果在 JVM 启动之前,明确中指定了上面的 JVM 配置:

# "skywalking." 是 Skywalking 环境变量的默认前缀
-Dskywalking.agent.service_name = hailtaxi-driver

2)探针配置笼罩

将 Java Agent 配置为如下:

# 默认格局是 -javaagent:agent.jar=[option1]=[value1],[option2]=[value2]
-javaagent:/path/skywalking-agent.jar=agent.service_name=hailtaxi-driver

此时会应用该 Java Agent 配置值笼罩 agent.config 配置文件中 agent.service_name 默认值。

然而这些配置都有不同优先级,优先级如下:

探针配置 > JVM 配置 > 零碎环境变量配置 > agent.config 文件默认值

3.2.2 IDEA 集成应用 agent

1、批改 agent 中数据收集服务的地址:agent/config/agent.confg

collector.backend_service=${SW_AGENT_COLLECTOR_BACKEND_SERVICES:192.168.200.129:11800}

当然也能够同构 JVM 参数配置

2、应用探针配置为 3 个我的项目别离配置 agent:

1)hailtaxi-driver:

-javaagent:C:\developer\skywalking\apache-skywalking-apm-bin\agent\skywalking-agent.jar
-Dskywalking.agent.service_name=hailtaxi-driver

将下面配置赋值到 IDEA 中:

2)hailtaxi-order

-javaagent:C:\developer\skywalking\apache-skywalking-apm-bin\agent\skywalking-agent.jar
-Dskywalking.agent.service_name=hailtaxi-order

将下面配置赋值到 IDEA 中:

3)hailtaxi-gateway

-javaagent:C:\developer\skywalking\apache-skywalking-apm-bin\agent\skywalking-agent.jar
-Dskywalking.agent.service_name=hailtaxi-gateway

将下面配置赋值到 IDEA 中:

此时启动 IDEA,并拜访:http://192.168.200.129:8080 成果如下:

如果你要追踪 Gateway 的话,你会发现:无奈通过 gateway 发现路由的服务链路?

起因:Spring Cloud Gateway 是基于 WebFlux 实现,必须搭配上 apm-spring-cloud-gateway-2.1.x-plugin 和 apm-spring-webflux-x.x-plugin 两个插件

计划:将 agent/optional-plugins 下的两个插件 复制到 agent/plugins 目录下

3.3.3 生产环境应用 agent

生产环境应用,因而咱们须要将 agent 和每个我的项目的 jar 包上传到服务器上,上传 apache-skywalking-apm-bin/usr/local/server/skywalking,再将 工程 \hailtaxi-parent中的我的项目打包,并别离上传到服务器上,如下三个工程:

hailtaxi-order-1.0-SNAPSHOT.jar
hailtaxi-gateway-1.0-SNAPSHOT.jar
hailtaxi-driver-1.0-SNAPSHOT.jar

1)启动 hailtaxi-gateway

java -javaagent:/usr/local/server/skywalking/apache-skywalking-apm-bin/agent/skywalking-agent.jar -Dskywalking.agent.service_name=hailtaxi-gateway -jar hailtaxi-gateway-1.0-SNAPSHOT.jar &

2)启动 hailtaxi-driver

java -javaagent:/usr/local/server/skywalking/apache-skywalking-apm-bin/agent/skywalking-agent.jar -Dskywalking.agent.service_name=hailtaxi-driver -jar hailtaxi-driver-1.0-SNAPSHOT.jar &

3)启动 hailtaxi-order

java -javaagent:/usr/local/server/skywalking/apache-skywalking-apm-bin/agent/skywalking-agent.jar -Dskywalking.agent.service_name=hailtaxi-order -jar hailtaxi-order-1.0-SNAPSHOT.jar &

3.3 Rocketbot

后面咱们曾经实现了 SkyWalking 环境搭建和我的项目利用 agent 应用,咱们来看如何应用 SkyWalking 提供的 UI 界面—— Skywalking Rocketbot。

OAP 服务和 Rocket(其实就是个 web 我的项目)均已启动

3.3.1 Rocketbot- 仪表盘

具体细则可参考资料:Skywalking 仪表盘应用

Rocketbot 从多个方面展现了服务信息,咱们别离从多个方面进行解说。

上图中的【仪表盘】、【拓扑图】、【追踪】、【性能分析】、【日志】、【正告】属于性能菜单。

仪表盘属于数据统计性能,别离从服务热度、响应程度、服务个数、节点信息等展现统计数据。

  • Global Heatmap 面板:热力求,从全局展现了某段时间申请的热度。
  • Global Percent Response 面板:展现了全局申请响应工夫的 P99、P95、P75 等分位数。
  • Global Brief 面板:展现了 SkyWalking 能感知到的 Service、Endpoint 的个数。
  • Global Top Troughput 面板:展现了吞吐量前几名的服务。
  • Global Top Slow Endpoint 面板:展现了耗时前几名的 Endpoint。
  • Service (Avg) ResponseTime 面板:展现了指定服务的(均匀)耗时。
  • Service (Avg) Throughput 面板:展现了指定服务的(均匀)吞吐量。
  • Service (Avg) SLA 面板:展现了指定服务的(均匀)SLA(Service Level Agreement,服务等级协定)。
  • Service Percent Response 面板:展现了指定服务响应工夫的分位数。
  • Service Slow Endpoint 面板:展现了指定服务中耗时比拟长的 Endpoint 信息。
  • Running ServiceInstance 面板:展现了指定服务下的实例信息。

除了 SkyWalking Rocketbot 默认提供的这些面板,咱们还能够点击锁型按钮,自定义 Global 面板。在 ServiceInstance 面板中展现了很多 ServiceInstance 相干的监控信息,例如,JVM 内存应用状况、GC 次数、GC 耗时、CPU 使用率、ServiceInstance SLA 等等信息。

3.3.2 Rocketbot- 拓扑图

【拓扑图】展现以后整个业务服务的拓扑图。点击拓扑图中的任意节点,能够看到服务相应的状态信息,其中包含响应的均匀耗时、SLA 等监控信息。点击拓扑图中任意一条边,还能够看到一条调用链路的监控信息,其中会别离从客户端(上游调用方)和服务端(上游接管方)来观测这条调用链路的状态,其中展现了该条链路的耗时、吞吐量、SLA 等信息。

3.3.3 追踪

【追踪】次要用来查问 Trace 信息,如下图所示。在①处能够抉择 Trace 的查问条件,其中能够指定 Trace 波及到的 Service、ServiceInstance、Endpoint 以及 Trace 的状态持续含糊查问,还能够指定 TraceId 和工夫范畴进行准确查问。在②处能够间接依据申请连贯查找调用链路信息。在③处展现了 Trace 的简略信息。在④处能够抉择不同的形式展现追踪信息。

在这里,咱们不仅能看到调用链路信息,还能看到 MySQL 操作监控, 如下图:

谬误异样信息也能追踪, 如下图:

3.3.4 性能剖析

在传统的监控零碎中,咱们如果想要得悉零碎中的业务是否失常,会采纳过程监控、日志收集剖析等形式来对系统进行监控。当机器或者服务呈现问题时,则会触发告警及时告诉负责人。通过这种形式,咱们能够得悉具体哪些服务呈现了问题。然而这时咱们并不能得悉具体的谬误起因出在了哪里,开发人员或者运维人员须要到日志零碎外面查看谬误日志,甚至须要到实在的业务服务器上查看执行状况来解决问题。

如此一来,仅仅是发现问题的阶段,可能就会消耗相当长的工夫;另外,发现问题然而并不能追溯到问题产生具体起因的状况,也常有产生。这样反反复复极其消耗工夫和精力,为此咱们便有了基于分布式追踪的 APM 零碎。

通过将业务零碎接入分布式追踪中,咱们就像是给程序减少了一个放大镜性能,能够清晰看到实在业务申请的整体链路,包含申请工夫、申请门路,甚至是操作数据库的语句都能够看得一清二楚。通过这种形式,咱们联合告警便能够疾速追踪到实在用户申请的残缺链路信息,并且这些数据信息齐全是长久化的,能够随时进行查问,复盘谬误的起因。

然而随着咱们对服务监控了解的加深,咱们发现事件并没有那么简略。在分布式链路追踪中咱们有这样的两个流派:代码埋点和字节码加强。无论应用哪种形式,底层逻辑肯定都逃不过面向切面这个根底逻辑。因为只有这样才能够做到大面积的应用。这也就决定了它只能做到框架级别和 RPC 粒度的监控。这时咱们可能依旧会遇到程序执行迟缓或者响应工夫不稳固等状况,但无奈具体查问到起因。这时候,大家很天然的会思考到减少埋点粒度,比方对所有的 Spring Bean 办法、甚至次要的业务层办法都加上埋点。然而这种思路会遇到不小的挑战:

第一,减少埋点时零碎开销大,埋点笼罩不够全面。通过这种形式咱们的确能够做到具体业务场景具体分析。但随着业务一直迭代上线,弊病也很显著:大量的埋点无疑会加大系统资源的开销,造成 CPU、内存使用率减少,更有可能拖慢整个链路的执行效率。尽管每个埋点耗费的性能很小,在微秒级别,然而因为数量的减少,甚至因为业务代码重用造成反复埋点或者循环应用,此时的性能开销曾经无奈疏忽。

第二,动静埋点作为一项埋点技术,和手动埋点的性能耗费上非常相似,只是缩小的代码批改量,然而因为通用技术的特地,上一个挑战中提到的循环埋点和重复使用的场景甚至更为严重。比方抉择所有办法或者特定包下的所有办法埋点,很可能造成零碎性能彻底解体。

第三,即便咱们通过正当设计和埋点,解决了上述问题,然而 JDK 函数是宽泛应用的,咱们很难限度对 JDK API 的应用场景。对 JDK 过多办法、特地是非 RPC 办法的监控会造成零碎的微小提早危险。而且有一些根底类型和底层工具类,是很难通过字节码进行加强的。当咱们的 SDK 使用不当或者呈现 bug 时,咱们无奈具体得悉实在的谬误起因。

Skywalking 中能够使用性能分析剖析特定端点的性能,咱们须要先创立一个监控工作:

新建工作后,在右侧能够查看工作性能剖析报表,还能够点击剖析线程栈信息,如下图:

3.3.5 告警

SkyWalking 告警性能是在 6.x 版本新增的,其外围由一组规定驱动,这些规定定义在 config/alarm-settings.yml 文件中。告警的定义分为两局部:

  1. 告警规定:它们定义了应该如何触发度量警报,应该思考什么条件。
  2. Webhook(网络钩子):定义当正告触发时,哪些服务终端须要被告知
3.3.5.1 正告规定详解

Skywalking 每隔一段时间依据收集到的链路追踪的数据和配置的告警规定(如服务响应工夫、服务响应工夫百分比)等,判断如果达到阈值则发送相应的告警信息。发送告警信息是通过调用 webhook 接口实现,具体的 webhook 接口能够使用者自行定义,从而开发者能够在指定的 webhook 接口中编写各种告警形式,比方邮件、短信等。告警的信息也能够在 RocketBot 中查看到。

咱们能够进入到 Skywalking 容器中,再进入到 config 文件夹下就能够看到 alarm-settings.yml,如下图:

SkyWalking 的发行版都会默认提供 config/alarm-settings.yml 文件,外面事后定义了一些罕用的告警规定。如下:

# Licensed to the Apache Software Foundation (ASF) under one
# or more contributor license agreements.  See the NOTICE file
# distributed with this work for additional information
# regarding copyright ownership.  The ASF licenses this file
# to you under the Apache License, Version 2.0 (the
# "License"); you may not use this file except in compliance
# with the License.  You may obtain a copy of the License at
#
#     http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

# Sample alarm rules.
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
#  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_avg_rule:
#    metrics-name: endpoint_avg
#    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/notify/
#  - http://127.0.0.1/go-wechat/

告警规定配置项的阐明:

  • Rule name:规定名称,也是在告警信息中显示的惟一名称。必须以 _rule 结尾,前缀可自定义
  • Metrics name:度量名称,取值为 oal 脚本中的度量名,目前只反对 longdoubleint类型。
  • Include names:该规定作用于哪些实体名称,比方服务名,终端名(可选,默认为全副)
  • Exclude names:该规定作不用于哪些实体名称,比方服务名,终端名(可选,默认为空)
  • Threshold:阈值
  • OP: 操作符,目前反对 ><=
  • Period:多久告警规定须要被核实一下。这是一个工夫窗口,与后端部署环境工夫相匹配
  • Count:在一个 Period 窗口中,如果 values 超过 Threshold 值(按 op),达到 Count 值,须要发送警报
  • Silence period:在工夫 N 中触发报警后,在 TN -> TN + period 这个阶段不告警。默认状况下,它和 Period 一样,这意味着雷同的告警(在同一个 Metrics name 领有雷同的 Id)在同一个 Period 内只会触发一次
  • message:告警音讯

在配置文件中事后定义的告警规定总结如下:

  1. 在过来 10 分钟内服务均匀响应工夫超过 1 秒达 3 次
  2. 在过来 10 分钟内服务成功率低于 80% 达 2 次
  3. 在过来 10 分钟内服务 90% 响应工夫低于 1 秒达 3 次
  4. 在过来 10 分钟内服务的响应工夫超过 1 秒达 2 次
  5. 在过来 10 分钟内端点的响应工夫超过 1 秒达 2 次

这些正告信息最终会在 Skywalking-UI 上展现,成果如下:

3.3.5.2 Webhook 规定

Webhook 配置其实是正告音讯接管回调解决,咱们能够在程序中写一个办法接管正告信息,Skywalking 会以 application/json 格局通过 http 申请发送,音讯格局申明为:List<org.apache.skywalking.oap.server.core.alarm.AlarmMessage

字段如下:

  • scopeId, scope: 所有的 scope 实体在 org.apache.skywalking.oap.server.core.source.DefaultScopeDefine 外面申明。
  • name. 指标 scope 实体名称。
  • id0: scope 实体 ID,匹配名称。
  • id1: 不应用。
  • ruleName: 配置在 alarm-settings.yml 外面的规定名称.
  • alarmMessage: 告警信息.
  • startTime:触发告警的工夫 示例:
[
  {
    "scopeId": 2,
    "scope": "SERVICE_INSTANCE",
    "name": "c00158f28efc45cd813e21b6b8848a3a@192.168.1.104 of hailtaxi-driver",
    "id0": "aGFpbHpdmVy.1_YzAwMAMTkyLjE2OC4xLjEwNA\u003d\u003d",
    "id1": "","ruleName":"service_instance_resp_time_rule","alarmMessage":"Response time of service instance c00158f28efc45cd813e21b6b8848a3a@192.168.1.104 of hailtaxi-driver is more than 1000ms in 2 minutes of last 10 minutes","startTime": 1611612258056
  }
]
3.3.5.3 自定义 Webhook 音讯接管

咱们依照如下步骤,能够在本人程序中接管正告信息:

1)定义音讯接管对象

hailtaxi-api 中创立com.itheima.skywalking.model.AlarmMessage,代码如下:

@Data
@ToString
@AllArgsConstructor
@NoArgsConstructor
public class AlarmMessage {
    private int scopeId;
    private String name;
    private String id0;
    private String id1;
    private String alarmMessage;
    private long startTime;
    String ruleName;
}

2)接管正告办法创立

hailtaxi-driver 中创立 com.itheima.driver.controller.AlarmMessageController 用于接管正告音讯,代码如下:

个别状况下,这种接管告警的 api 会被搁置在比拟安闲的后盾服务中!!!

@RestController
@RequestMapping(value = "/skywalking")
public class AlarmMessageController {

    /***
     * 接管正告信息
     * @param alarmMessageList
     */
    @PostMapping("/webhook")
    public void webhook(@RequestBody List<AlarmMessage> alarmMessageList) {for (AlarmMessage alarmMessage : alarmMessageList) {System.out.println("webhook:"+alarmMessage);
        }
    }
}

3)批改 Webhook 地址

批改 alarm-settings.yml 中的 webhook 地址:

webhooks:
#  - http://127.0.0.1/notify/
#  - http://127.0.0.1/go-wechat/
   - http://192.168.200.10:8001/driver/skywalking/webhook

因为 skywalking 默认有一个告警规定:10 分钟内服务成功率低于 80% 超过 2 次

所以为了能演示出告警成果,咱们在 hailtaxi-driver 我的项目中的 driver/info 接口中增加一个一句话

/****
   * 司机信息
   */
  //@GetMapping(value = "/info/{id}")
  @RequestMapping(value = "/info/{id}")
  public Driver info(@PathVariable(value = "id")String id,HttpServletRequest request){
      int i = 1/ 0; // 产生异样
      Enumeration<String> headerNames = request.getHeaderNames();
      while (headerNames.hasMoreElements()){String name = headerNames.nextElement();
          String value = request.getHeader(name);
          System.out.println(name+":"+value);
          System.out.println("--------------------------");
      }
      return driverService.findById(id);
  }

测试时将网关的条件断言给正文一下!!!

此时咱们程序中就能接管正告信息了。

本文由传智教育博学谷 – 狂野架构师教研团队公布,转载请注明出处!

如果本文对您有帮忙,欢送关注和点赞;如果您有任何倡议也可留言评论或私信,您的反对是我保持创作的能源

正文完
 0