skywalking学习与应用笔记

研究一下skywalking+elasticsearch实现分布式链路追踪微服务

备注:

skywalking版本使用的是6.6.0
elasticsearch的版本6.8.3
skywalking对es的版本号有一定的要求,最好使用6.3.2以上版本,如果是7.x的版本,需要额外进行配置。

1.基础概念

skywalking是一个分布式链路追踪技术,为服务(service),服务实例(service instance),端点(endpoint)提供了观测能力。
服务:可以理解为saas的user,store,coupon等微服务
服务实例:例如正式环境ops部署了6台2核4G的机器,每台机器就是一个实例
端点:理解为ops的一个接口url

2.搭建方法

windows系统搭建不断报错,所以直接在linux系统搭建

2.1.搭建elasticsearch

这里需要注意下es的集群端口号的问题,es的集群端口号默认是9300,根据一些博客所说,不可以修改集群的第一个节点的端口号,否则会导致后面的节点无法加入到集群中。

2.1.1.搭建linux系统的es

1.修改系统中允许应用最多创建多少文件等的限制权限,linux默认,一般限制应用最多创建的文件是65536个,而es至少需要65536的文件创建数权限。

2.修改系统中允许用户启动的进程开启多少个线程。默认的linux限制root用户开启的进程可以开启任意数量的线程,其他用户开的的进程可以开启1024个线程,必须修改限制数为4096+。因为es至少需要4096的线程池预备。

vi /etc/security/limits.conf
#新增以下配置
es soft nofile 65536
es hard nofile 65536
es soft nproc 4096
es hard nproc 4096

3.修改系统控制权限,es需要开辟一个65536个字节以上空间的虚拟内存,linux默认不允许任何用户和应用程序直接开辟这么大的虚拟内存。

vi /etc/sysctl.conf
#新增
vm.max_map_count = 262144

保存后退出 vi编辑器
让系统控制权限生效

sysctl -p

4.新建一个用户,用于es的启动。
因为es在5.x以上的版本之后,强制要求在linux中不能使用root用户启动es进程,所以必须使用其他用户启动es才可以。

#创建用户
useradd es
#修改密码,自定义一个密码
passwd es
#修改elasticserach目录的拥有者 ,以下命令最后一个是es的安装目录名称
chmod -R es elasticsearch-6.8.3  
#切换用户 es
#进入elasticsearch的安装目录下bin文件夹,通过elasticsearch.sh来启动es

启动完成之后,可以通过curl http://localhost:9200观看是否启动成功
在这里插入图片描述

2.2.linux系统搭建skywalking

2.2.1.搭建skywalking

#切换到root用户
su root

解压skywalking,切换到skywalking的安装目录中,如下图所示,skywalking需要改动的配置主要是config目录下的application.yml和webapp目录下的webapp.yml
在这里插入图片描述

2.2.2.修改skywalking的配置文件

#修改skywalking的配置文件,修改skywalking存储的数据源配置,全部改成es并且注释H2的配置,如下图2所示。

vi config/application.yml

图片: https://uploader.shimo.im/f/lJpQXIgMJAl52NBI.png

修改webapp目录下的webapp.yml中的端口号,主要的避免端口号冲突:我改成了9010
图片: https://uploader.shimo.im/f/RLUWh7c41x28yz97.png

2.2.3.启动skywalking
切换到skywalking的bin目录下,启动startup.sh
图片: https://uploader.shimo.im/f/mKjaWOY0r3P3eff3.png

这时候skywalking目录下会出现logs目录,进入其中,可以看到启动日志webapp.log
图片: https://uploader.shimo.im/f/rAquZ9iA1TM5Ibpa.png

注意下确认,你的云服务器有没有开通9010端口。
如果没有开通的话,去云服务器的安全组去开放端口号,如果已经开通了,那么可以通过你的服务器的ip+端口号就能访问到skywalking了。
图片: https://uploader.shimo.im/f/WHGvy7A3fVg3mHu7.png

2.3.测试skywalking监控demo微服务

写一个demo微服务测试一下skywalking的监控。

2.3.1.介绍skywalking的agent

首先,注意下skywalking目录下的agent目录,其中/agent/config/目录下的agent.config是配置文件,plugins是默认的所有的组件插件,optional-plugins是可选的插件,最后
skywalking-agent.jar这个jar包是最重要的。启动微服务的时候,需要指明这个jar包的位置。

注意:微服务可以共用一个agent。也可以每个微服务单独使用各自的agent,可以通过命令 cp -r agent agent_ops复制。

共用一个agent的话,使用

java -javaagent:/path/skywalking-agent.jar -Dskywalking.agent.service_name=某某 -jar 微服务.jar &
或
java -javaagent:/path/skywalking-agent.jar=agent.service_name=某某 -jar 微服务.jar &

图片: https://uploader.shimo.im/f/ryARSIvFyYXIsk17.png

2.3.2.修改agent/config/agent.config配置文件

修改的是agent.service_name这个值,目前改成testdemo,以后上线的话,可以修改成ops,order等等微服务的名称

图片: https://uploader.shimo.im/f/laQneORki87jl0LZ.png

2.3.3.编写testdemo
我写的这个springboot微服务的端口号是8899

package com.skywalking.testdemo.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SkyWalkingDemoController {

    public static final Logger log = LoggerFactory.getLogger(SkyWalkingDemoController.class);

    @GetMapping("getOrderNo")
    public String getOrderNoTest4SkyWalking() {
        return "dushanTest122212321312";
    }

    @GetMapping("/exception")
    public String testException(){
        int i =1/0;
        return "hello exception";
    }

}

打包,上传到服务器,jar包名称testdemo.jar,启动jar包,注意命令如下:

java -javaagent:/data/apache-skywalking-apm-bin/agent/skywalking-agent.jar -jar testdemo.jar &

启动成功,注意你的服务器有没有开通8899端口号,然后在浏览器上访问写的这两个接口。
图片: https://uploader.shimo.im/f/g4aXX9uWDz8kOKqu.png
图片: https://uploader.shimo.im/f/utTzMTPU5RhWk7AP.png

图片: https://uploader.shimo.im/f/YK9hMzeKKk5DI9WP.png

这个时候再去访问skywalking,就能看到调用结果。

注意:一定要注意右下角的时间,坑的要死,之前试验了很多次,都没有结果,最后发现这个右下角的时间选项有问题,选择你测试的那个时间段,就能看到结果了。
图片: https://uploader.shimo.im/f/0uL8iz5mNa43SpRW.png

2.4.skywalking页面参数意义

2.4.1.首页

2.4.1.1.查看:

图片: https://uploader.shimo.im/f/KqLhoe9pirpSm02h.png

2.4.1.2.按照服务维度查看:

图片: https://uploader.shimo.im/f/12zNFFLJp9JCtkcY.png

2.4.1.3.按照端点维度查看:

图片: https://uploader.shimo.im/f/1FfNjPN9fMtiyTN7.png

2.4.1.4.按照实例维度查看

还能看到JVM,GC和CPUI占用率:
图片: https://uploader.shimo.im/f/OeWUwKSxJ8lPnZap.png

2.4.2.拓扑图

点击拓扑图,可以看到当前服务的连接和调用情况,之后还可以看服务间的调用情况:
图片: https://uploader.shimo.im/f/tiS3KxeFl55mJpP3.png

2.4.3.追踪

点开页面中的追踪页面,蓝色代表,接口调用成功,红色代表接口调用失败,并且页面最上,可以选择服务,实例,状态,进行筛选,
图片: https://uploader.shimo.im/f/YFN1x4QC6XhCbbvK.png

点击页面右侧接口,就能看到接口调用详情。例如点击上图中的exception
图片: https://uploader.shimo.im/f/dZkBpJxxN4gXI9kR.png

2.4.4.告警

上线的时候可以选择是否配置

2.4.4.1.简介:

skywalking每隔一段时间根据收集到的链路追踪的数据和配置的告警规则(服务器响应时间,服务响应时间的百分比)等,判断如果达到阈值则发送响应的告警信息,发送告警信息是通过调用webhook接口完成,具体的webhook接口可以自定义,从而开发者可以在指定的webhook接口中编写各种告警方式,邮件,短信等,告警信息,也可以在RocketBot中查看到。

默认的告警规则,在skywalking目录下的config目录下的alarm-setting.yml文件,如下,我删除了无用的注释。

# Sample alarm rules.
rules:
  # Rule unique name, must be ended with `_rule`.
  #下面这个代表对服务的相应时间做的一个规则
  service_resp_time_rule:
	#oal脚本中的度量名称,这里代表的是服务的相应时间
    metrics-name: service_resp_time
    op: ">"
	#1秒
    threshold: 1000
	#多久检查一次,默认是10分钟
    period: 10
	#达到多少次后发送报警消息
    count: 3
	#在多久之内,忽略报警信息,下面这个代表,当这个告警发生之后,在5分钟内不会重复发送
    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_p90_sla_rule:
    # Metrics value need to be long, double or int
    metrics-name: service_p90
    op: ">"
    threshold: 1000
    period: 10
    count: 3
    silence-period: 5
    message: 90% response time of service {name} is more than 1000ms in 3 minutes of last 10 minutes
  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/
2.4.4.2.新增超时接口和回调接口
package com.skywalking.testdemo.controller;

import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SkywalkingAlarmController {

    //超时告警
    @GetMapping("timeout")
    public String timeout(){
        try {
            Thread.sleep(1500);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return "timeout";
    }
}

基础类:
注意这个基础类,skywalking6.x和5.x的版本,基础类不同,所以如果你的基础类缺少字段,可能导致回调接口没有起作用。我的版本是6.x。
不同的版本去github中的skywalking项目中的
skywalking/oap-server/server-core/src/main/java/org/apache/skywalking/oap/server/core/alarm/AlarmMessage.java类中去看字段

package com.skywalking.testdemo.pojo;

public class AlarmMessage {

    private int scopeId;
    private String scope;
    private String name;
    private int id0;
    private int id1;
    private String ruleName;
    private String alarmMessage;
    private long startTime;

    public int getScopeId() {
        return scopeId;
    }

    public void setScopeId(int scopeId) {
        this.scopeId = scopeId;
    }

    public String getScope() {
        return scope;
    }

    public void setScope(String scope) {
        this.scope = scope;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getId0() {
        return id0;
    }

    public void setId0(int id0) {
        this.id0 = id0;
    }

    public int getId1() {
        return id1;
    }

    public void setId1(int id1) {
        this.id1 = id1;
    }

    public String getRuleName() {
        return ruleName;
    }

    public void setRuleName(String ruleName) {
        this.ruleName = ruleName;
    }

    public String getAlarmMessage() {
        return alarmMessage;
    }

    public void setAlarmMessage(String alarmMessage) {
        this.alarmMessage = alarmMessage;
    }

    public long getStartTime() {
        return startTime;
    }

    public void setStartTime(long startTime) {
        this.startTime = startTime;
    }
}

回调接口:

package com.skywalking.testdemo.controller;

import com.alibaba.fastjson.JSON;
import com.skywalking.testdemo.pojo.AlarmMessage;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.*;

import java.util.ArrayList;
import java.util.List;

@RestController
public class WebHooks {

    public static final Logger log = LoggerFactory.getLogger(WebHooks.class);

    private List<AlarmMessage> lastList = new ArrayList<>();

    //接受到报警消息后,传给参数list
    @RequestMapping(value = "/webhook", method = RequestMethod.POST)
    public void webhook(@RequestBody(required = false) List<AlarmMessage> alarmMessageList) {
        log.info("list ={}", JSON.toJSONString(alarmMessageList));
        lastList = alarmMessageList;
    }

    //浏览器显示报警消息
    @GetMapping("/show")
    public List<AlarmMessage> show() {
        return lastList;
    }
}

2.4.4.3修改服务器中的skywalking的告警规则
修改回调接口,并重启:
图片: https://uploader.shimo.im/f/RqsA1eCWBWQHojbW.png

图片: https://uploader.shimo.im/f/Lz0aLmXSVL44m28b.png

默认的告警规则是,超过3次,都超时,就触发告规则,那就多次调用接口
ip:8899/timeout
再接着就能在skywalking中的告警页面看到告警信息:
图片: https://uploader.shimo.im/f/gTDDGDnX6vqeusLc.png

再调用ip:8899/show就能看到告警信息的list
图片: https://uploader.shimo.im/f/rReYNiraph45RfwD.png

2.4.5.指标对比

用于当出现异常的时候,对两个实例之间进行对比,看看这两个实例,在相应时长等信息是否在一个维度,如果不在一个等级上,则某个实例可能出现了问题。
图片: https://uploader.shimo.im/f/5Zi2qPa8gWD6MOjK.png

2.5.skywalking监控mysql

新增接口,访问数据库中的user表,user表就2个字段,id和username.
链接数据库的配置就不卸载文档中了。重新打包,上传,重启。

package com.skywalking.testdemo.controller;

import com.skywalking.testdemo.dao.UserRepository;
import com.skywalking.testdemo.pojo.User;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

@RestController
public class Skywalking4MysqlController {

    @Resource
    private UserRepository userRepository;

    @GetMapping("/userList")
    public List<User> finadAll() {
        List<User> list = new ArrayList<>();
        userRepository.findAll().forEach((user) -> {
            list.add(user);
        });
        return list;
    }
}

pojo:

package com.skywalking.testdemo.pojo;

import org.springframework.data.annotation.Id;
import org.springframework.data.relational.core.mapping.Table;

@Table("user")
public class User {

    @Id
    private Long id;

    private String username;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }
}

repository:

package com.skywalking.testdemo.dao;

import com.skywalking.testdemo.pojo.User;
import org.springframework.data.repository.CrudRepository;

public interface UserRepository extends CrudRepository<User, Integer> {

}

在浏览器中访问接口
图片: https://uploader.shimo.im/f/oPhbAOH2FjwzGiI7.png

再次刷新skyywalking仪表盘首页,可以看到这个接口调用情况如下图:
图片: https://uploader.shimo.im/f/5DYJiprbi5rhXH3i.png

切换到数据库页面
图片: https://uploader.shimo.im/f/R671SwXmqkRZgnFz.png

进入到追踪页面,点击右侧的接口,可以看到sql语句和sql语句的执行时间
图片: https://uploader.shimo.im/f/uijB3pWVC3F2c5tr.png

点击1的结果:
图片: https://uploader.shimo.im/f/Z5rb2JgLeNFMaQNy.png

点击2的结果:
图片: https://uploader.shimo.im/f/fK6usDous7QgOAka.png

2.6.获取skywalking的追踪ID

引入jar包:

<properties>
    <java.version>1.8</java.version>
    <skywalking.version>6.6.0</skywalking.version>
</properties>

<dependency>
    <groupId>org.apache.skywalking</groupId>
    <artifactId>apm-toolkit-trace</artifactId>
    <version>${skywalking.version}</version>
</dependency>

修改原先2.3.3的接口:增加:TraceContext.traceId()

package com.skywalking.testdemo.controller;

import org.apache.skywalking.apm.toolkit.trace.TraceContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class SkyWalkingDemoController {

    public static final Logger log = LoggerFactory.getLogger(SkyWalkingDemoController.class);

    @GetMapping("getOrderNo")
    public String getOrderNoTest4SkyWalking() {
        log.info("getOrderNoTest4SkyWalking function start and traceId = {}", TraceContext.traceId());
        return "dushanTest122212321312";
    }

    @GetMapping("/exception")
    public String testException() {
        try {
            int i = 1 / 0;
            return "hello exception";
        } catch (Exception e) {
            log.error("traceId = {},exception of testException ={}", TraceContext.traceId(), e.getMessage());
        }
        return "fuck error";
    }

}

打包,上传,运行,访问。
再次调用接口,就能在日志中获取skywalking的traceId
图片: https://uploader.shimo.im/f/dpncumH3E8E89wdK.png

复制这个traceId,可以去skywalking的追踪页面进行搜索,查询到接口的调用情况
图片: https://uploader.shimo.im/f/YoxY4V7UirgpUStP.png

  • 0
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值