SkyWalking

SkyWalking

Skywalking简介

SkyWalking是一个开源的可观察性平台,用于收集,分析,聚合和可视化来自本地或者云服务中的数据。即使在整个云环境中,SkyWalking也能提供一种简便的方法来维护您的分布式系统的清晰视图。它是一个现代的APM(Application Performance Monitor 应用性能监测软件),专门为基于云、容器的分布式系统而设计。

为什么要选择skywalking?

SkyWalking提供了用于在许多不同情况下观察和监视分布式系统的解决方案,并通过agent方式,做到高性能、低损耗、无侵入性,与类似的功能组件如:Zipkin、Pinpoint、CAT相比,skywalking无论是从性能还是社区活跃度方面考虑,都具有一定的优势。

skywalking监控维度

skywalking从三个维度提供可观察项功能,分别是:服务,服务实例,端点

服务。表示一组/一组工作负载,这些工作负载为传入请求提供相同的行为。
服务实例。服务组中的每个单独工作负载都称为实例。像pods在Kubernetes中一样,它不必是单个OS进程,但是,如果您使用agent代理,则实例实际上是一个真正的OS进程。
端点。服务中用于传入请求的路径,例如HTTP URI路径或gRPC服务类+方法签名。

skywalking架构

从逻辑上看,skywalking分为四个部分:探针,平台后端,存储和UI。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

探针:收集数据并重新格式化以符合SkyWalking的要求(不同的探针支持不同的来源)。
平台后端:支持数据聚合,分析和流处理,涵盖跟踪,指标和日志。
存储:设备通过开放/可插入的界面存储SkyWalking数据。您可以选择现有的实现,例如ElasticSearch,H2,MySQL,TiDB,InfluxDB,或者实现自己的实现。
UI:是一个高度可定制的基于Web的界面,允许SkyWalking最终用户可视化和管理SkyWalking数据。

skywalking安装

直接进入官方下载:https://skywalking.apache.org/downloads/ 下载之后上传到服务器并安装

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

agent目录:将来要拷贝到各服务所在机器上用作探针
bin目录:服务启动脚本
config:配置文件
oap-libs:oap服务运行所需要的jar包(oap服务就是skywalking的后端服务Observability Analysis Platform)
webapp:web服务运行所需要的jar包

启动

cd到bin目录

执行./startup.sh直接同时启动 oap和web服务

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

访问

访问你的服务器地址,8080端口,就可以进入skywalking的UI界面

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

替换存储源

默认情况下skywalking使用H2来存储数据,这肯定无法满足性能要求,所以我们使用ES来进行存储。

elasticsearch安装

下载

下载elasticsearch,本教程选择6.4.0版本

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

解压、启动

同样直接解压,并进入elasticsearch-6.4.0目录

进入bin目录,启动./elasticserach,你可能会遇到如下报错,表明不能使用root用户启动es

org.elasticsearch.bootstrap.StartupException: java.lang.RuntimeException: can not run elasticsearch as root
at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:140) ~[elasticsearch-6.4.0.jar:6.4.0]
at org.elasticsearch.bootstrap.Elasticsearch.execute(Elasticsearch.java:127) ~[elasticsearch-6.4.0.jar:6.4.0]
at org.elasticsearch.cli.EnvironmentAwareCommand.execute(EnvironmentAwareCommand.java:86) ~[elasticsearch-6.4.0.jar:6.4.0]
at org.elasticsearch.cli.Command.mainWithoutErrorHandling(Command.java:124) ~[elasticsearch-cli-6.4.0.jar:6.4.0]
at org.elasticsearch.cli.Command.main(Command.java:90) ~[elasticsearch-cli-6.4.0.jar:6.4.0]
at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:93) ~[elasticsearch-6.4.0.jar:6.4.0]
at org.elasticsearch.bootstrap.Elasticsearch.main(Elasticsearch.java:86) ~[elasticsearch-6.4.0.jar:6.4.0]
Caused by: java.lang.RuntimeException: can not run elasticsearch as root
at org.elasticsearch.bootstrap.Bootstrap.initializeNatives(Bootstrap.java:104) ~[elasticsearch-6.4.0.jar:6.4.0]
at org.elasticsearch.bootstrap.Bootstrap.setup(Bootstrap.java:171) ~[elasticsearch-6.4.0.jar:6.4.0]
at org.elasticsearch.bootstrap.Bootstrap.init(Bootstrap.java:326) ~[elasticsearch-6.4.0.jar:6.4.0]
at org.elasticsearch.bootstrap.Elasticsearch.init(Elasticsearch.java:136) ~[elasticsearch-6.4.0.jar:6.4.0]
… 6 more

所以我们需要重新建一个用户,并用新用户启动es

比如我重新建立了一个用户就叫es

启动

启动成功后,我们通过curl http://localhost:9200测试,看到如下内容就表示es启动成功。

你也可以使用如下命令,用后台方式启动。

./elasticsearch -d

配置外部访问

cd到elasticsearch的config目录中

修改elasticsearch.yml文件,找到network.host配置项,默认是注释着的,打开注释,并修改为0.0.0.0,保存退出,重启es服务即可。

vi elasticsearch.yml

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

那么现在就可以通过外部访问了

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

替换skywalking存储方式为es

现在es服务已经配置完成了,我们cd到skywalking的 config目录下

修改application.yml文件

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

找到存储源的配置,直接把h2改成es即可

默认配置:

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

换成:elasticsearch

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

保存并启动skywalking

看到日志中有创建一些es索引的过程,表示已经成功使用es作为存储源了

配置agent

现在skywalking还无法监控服务,需要我们配置agent,skywalking提供的agent本身就是一个jar包,所以启动时直接新增javaagent配置项,指定好skywalking-agent.jar的所在的路径即可。

idea集成
为了演示方便,直接使用idea配置启动。

首先配置javaagent:指定agent目录下的skywalking-agent.jar所在的路径
service_name名称根据自己的情况定义
然后注意backend_service,端口为11800 grpc访问的端口

-javaagent:D:/learn/skywalking/apache-skywalking-apm-bin/agent/skywalking-agent.jar
-Dskywalking.agent.service_name=order
-Dskywalking.collector.backend_service=10.0.0.189:11800

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

配置完启动服务,此时再访问就可以看到你的服务了

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

接口测试一下

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

我们可以看到,本身Rocketbot UI,也为我们从4个角度进行了监控,全局的,服务、实例、端点,一开始也提到过后面3个本身也是skywalking的监控维度

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

那我们再启动一个微服务,并且通过feign的方式,进行微服务之间的调用,那我们可以看到结果如下,skywalking可以为我们监控到每一次请求所执行的路径,已经每个路径上的耗时时间。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

总结

skywalking拥有完整的APM和调用链路功能,扩展性强、二次开发简单,使用agent采集数据,并经过collector简单处理数据、aggregator聚合数据统计分析并持久化、alarm监控告警,最终提供query查询,和UI呈现。

自定义链路追踪:

例如希望追踪某个业务方法的入参及返回值(点击链路即可看到信息)

第一步:需要引入依赖

<dependency>
    <groupId>org.apache.skywalking</groupId>
    <artifactId>apm-toolkit-trace</artifactId>
    <!-- 和sw的版本一致即可 -->
    <version>8.5.0</version>
</dependency>

第二步:在业务方法上面加上@Trace注解 (该注解为记录方法注解)

第三步:再追加上@Tags或@Tag注解 (该注解用于记录方法的入参或返回值)

key一般可以指定为方法名或参数名(自定义),

value不能随便填 arg[0]表示下标为0的参数 ,returnedObj表示返回值

@Trace
@Tags({@Tag(key = "param", value = "arg[0]"), @Tag(key = "test", value = "returnedObj")})
private String test(String param) {
    return "xxx";
}

性能剖析:
可以定位到具体代码 占用时间

操作方法:性能剖析页面点击新建任务
选择实例服务 输入端点名称(接口相对路径url)

skywalking链路追踪与logback日志整合
需要在oap-libs 目录中加上 log4j-web.jar
(忘记了自己最早为什么写的需要这个包,
后面经过测试可以不加 但基于对自己的信任 这句话先留着 万一就踩坑了呢)

第一步: 在pom文件中添加整合依赖

<!-- skywalking和logback整合 print traceId in our logs-->
<dependency>
    <groupId>org.apache.skywalking</groupId>
    <artifactId>apm-toolkit-logback-1.x</artifactId>
</dependency>

第二步: 在resources下新建名为logback-spring.xml 的文件

<?xml version="1.0" encoding="UTF-8" ?>
<configuration>
    <!-- 引入springboot 默认的 logback xml 配置文件 (springboot default log config)-->
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>

    <appender name="console" 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.TraceIdPatternLogbackLayout">
                <!-- 来源于defaults.xml 可以全局查找文件找到springboot中的该配置文件 如果无需更改 只需要引入>${CONSOLE_LOG_PATTERN}-->
                <!-- 我们需要记录traceId 所以需要加上[%tid] 加在下面任意一个不破坏格式的地方-->
                <!--source from springboot logback defaults.xml,default:${CONSOLE_LOG_PATTERN}
                 but we need to note the traceId ,add [%tid]-->
                <!-- https://github.com/apache/skywalking/tree/master/docs/en/setup/service-agent/java-agent -->
                <Pattern>-%clr(%d{${LOG_DATEFORMAT_PATTERN:-yyyy-MM-dd HH:mm:ss.SSS}}){faint}%clr(${LOG_LEVEL_PATTERN:-%5p}) %clr(${PID:- }){magenta} [%tid] %clr(---){faint}%clr([%15.15t]){faint} %clr(%-40.40logger{39}){cyan} %clr(:){faint}%m%n${LOG_EXCEPTION_CONVERSION_WORD:-%wEx}</Pattern>

            </layout>

        </encoder>
    </appender>

    <!-- grpc方式将traceId推送至skywalking-->
    <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>


    <!--设置appender -->
    <root level="INFO">
        <appender-ref ref="console"/>
        <appender-ref ref="grpc-log"/>
    </root>

</configuration>

注意:当skyWalking部署在远程服务的时候 需要在./agent/config目录下面对agent.config配置文件追加:
SW_GRPC_LOG_SERVER_HOST 对应服务地址 没有该配置默认为127.0.0.1

plugin.toolkit.log.grpc.reporter.server_host=${SW_GRPC_LOG_SERVER_HOST:192.168.0.1}
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}


这里有个坑,如果配置反复检查没有配错,skywalking的控制台仍看不到日志信息(如果能看到直接跳过),那看看是不是和我一样踩坑了:

因为我是在个人项目中搭建的,个人项目之前为了模拟传说中的log4j史诗级bug, 需要把logback等日志的实现给排除 (log4j其实只是接口 真正的bug位于log4j-core包),所以我把springboot中 最常用的这个spring-boot-starter-logging包给排除了,等到需要skywalking和logback整合的时候 又单独引用了slf4j-api,logback-core,logback-classic 三个依赖,结果发现一直显示不了日志。 最后想来想去 应该是日志依赖这边出了问题,删除单独引入的依赖,直接引入starter-logging依赖,成功解决问题。

   <!-- skyWalking与logback整合 需要的logback依赖
        且已测试只加入slf4j-api logback-core与logback-classic这三个包无效 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-logging</artifactId>
            <!-- 测试log4j bug时 需要排除starter-logging包下所有依赖 -->

      <!--      <exclusions>
                <exclusion>
                    <groupId>*</groupId>
                    <artifactId>*</artifactId>
                </exclusion>
            </exclusions>-->
        </dependency>

告警功能

SkyWalking告警功能是在6.x版本新增的的,其核心由一组规则驱动,这些规则定义在config目录的alarm-settings.yml文件中。
SkyWalking的发行版都会默认提供该配置,里面预先定义了一些常用的告警规则

1. 过去3分钟内服务平均响应时间超过1秒
2.过去2分钟服务成功率低于80%
3.过去3分钟内服务响应时间超过1s的百分比
4,服务实例在过去2分钟内平均响应时间超过1s.并且实例名称与正则表达式匹配,
5.过去2分钟内端点平均响应时间超过1秒
6.过去2分钟内数据库访问平均炯应时间超过1秒
7.过去2分钟内端点关系平均响应时间超过1秒。

告警规则配置项的说明
规则名称: 告警信息中显示的唯一名称。必须以过 _rule 结尾,前綴可自定义

Metrics name:配置时只需要取 _rule 前的名称;度量名称,取值为oal脚本中的度量,目前只支持long、double和Int型

Include names:该规则作用于哪些实体名称,比如服务名,终端名(可选,默认为全部〕

Exclude names:该规则作不用于哪些实体名称,比如服务名,终惴名(可选,默认为空)

Threshold:阈值, 例如2000为2s

OP:操作符,目前支持> < =

Period:多久告警规则需要被核实一下。这是一个时间窗囗,与后端部署环境时间相匹配

Count: 在一个Period窗口中,如值values超过Threshold值(按op) 达到count值需要发送警报

Silence period : 在时间N中 触发报警后,在TN->TN+ period 这个阶段不告警 ,默认情况下 它和period一样,意味着相同的告警 在同一个period内只会触发一次

webhooks: 网络钩子 可以理解为web回调 出现告警时,可以往我们任意一个服务发送请求,
我们可以在服务里面写业务代码:如发送短信、邮件等 请求方式:http, post, Content-type:application/json

基于List<org.apache.skywalking.oap.server.core.alarm.AlarmMessage>进行序列化的
,可以自定义一个类 字段保持上述一致

配置示例

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
    exclude-labels:
    # 过滤状态码 200 401 404  注意前面有个小横杠
      - "200,401,404"
    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

告警面板

skywalking的告警页面,可以看到我们的告警信息。如果之前的告警 页面突然看不到了,看看是不是时间筛选的问题,默认的时间跨度不会很长,不得不吐槽其它页面上方都有时间筛选 而告警页面只有右下角才有,每次搭建后都以为是出现了bug。

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

告警通知

上面介绍的是告警功能,只能在skywalking的控制台面板上看到,那如果我们想要通知功能该怎么办呢? 同样是在config目录的alarm-settings.yml配置中

找到webhooks:节点

外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传

注意前面有个 横杠 - ,建议打开注释并修改默认地址 避免出错,指定接口后,skywalking告警消息在短暂的延迟后会调用我们的接口进行通知, 我们可以在接口里面写发送邮件、发送短信 、通知到钉钉群等代码功能,取决于我们需求。

接下来演示告警信息发送邮件

1、配置回调接口

在 config/alarm-settings.yml中配置回调接口(我们应用服务的接口),并重启 skywalking服务。

webhooks:
#  - http://127.0.0.1/notify/
#  - http://127.0.0.1/go-wechat/
  - http://127.0.0.1:18081/sw/alarm/notify/
  - http://127.0.0.1:18081/sw/alarm/notify2/

2、编写回调接口

在我们应用服务中编写接口。拿到告警信息,通过不同的方式通知工作人员。

2.1 控制台输出告警信息

简单点,控制台输出告警信息。

@RestController
@RequestMapping("/sw/alarm")
public class SkywalkingAlarmController {

	/**
	 * Skywalking告警通知回调接口:http://127.0.0.1:18081/sw/alarm/notify/
	 * 
	 * @param obj
	 * @return
	 */
	@RequestMapping("/notify")
	public String notify(@RequestBody Object obj) {
		// TODO 将告警信息通知给负责人。比如:通过发短信,钉钉消息,邮件,微信通知等方式发送给技术负责人
		System.err.println("收到Skywalking告警信息:" + obj.toString());
		return "notify successfully";
	}
    
}

2.2 发送邮件

SpringBoot 实现发送邮件:https://blog.csdn.net/qq_42402854/article/details/110472398

	/**
	 * 发送邮件
	 *
	 * Skywalking告警通知回调接口:http://127.0.0.1:18081/sw/alarm/notify2/
	 *
	 * @param obj
	 * @return
	 */
	@RequestMapping("/notify2")
	public String notify2(@RequestBody Object obj) {
		// TODO 将告警信息通知给负责人。比如:通过发短信,钉钉消息,邮件,微信通知等方式发送给技术负责人
		System.err.println("notify2 收到Skywalking告警信息:" + obj.toString());

		sendSimpleMail("xxx@qq.com", "Skywalking告警信息", obj.toString());
		return "notify successfully";
	}

	private static final String SENDER = "xxx@163.com";
	@Autowired
	private JavaMailSender mailSender;

	/**
	 * 发送普通邮件
	 *
	 * @param to      收件人邮箱
	 * @param subject 主题(标题)
	 * @param content 内容
	 */
	public void sendSimpleMail(String to, String subject, String content) {
		SimpleMailMessage message = new SimpleMailMessage();
		message.setFrom(SENDER);
		message.setTo(to);
		message.setSubject(subject);
		message.setText(content);
		try {
			mailSender.send(message);
		} catch (Exception e) {
			System.out.println("发送普通邮件时发生异常!" + e);
		}
	}

ired
private JavaMailSender mailSender;

/**
 * 发送普通邮件
 *
 * @param to      收件人邮箱
 * @param subject 主题(标题)
 * @param content 内容
 */
public void sendSimpleMail(String to, String subject, String content) {
	SimpleMailMessage message = new SimpleMailMessage();
	message.setFrom(SENDER);
	message.setTo(to);
	message.setSubject(subject);
	message.setText(content);
	try {
		mailSender.send(message);
	} catch (Exception e) {
		System.out.println("发送普通邮件时发生异常!" + e);
	}
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值