1、基本介绍
SkyWalking是一个开源的观测平台,官网:Apache SkyWalking;
可监控:分布式追踪调用链 、jvm内存变化、监控报警、查看服务器基本配置信息。
2、SkyWalking架构原理
在整个skywalking的系统中,有三个角色:
1.skywalking agent 和业务系统(jar)关联在一起 ,负责收集各种监控数据;
2.skywalking oapservice负责处理监控数据 ,比如接受skywalking agent的监控数据,并存储在数据库中(例如elasticsearch、mysql中等);接受skywalking webapp的前端请求,从数据库查询数据,并返回数据给前端。,Skywalking oapservice通常以集群的形式存在;
3.skywalking webapp 前端界面,用于展示数据。
2.1、skywalking 底层原理流程
1.springboot项目启动的时候 是不需要引入任何的jar包,
2.启动springboot项目时被skywalking skywalking-agent.jar 代理拦截,
-- agent代理拦截是jdk提供的一种技术 ;可以使启动jar包时不需要引入任何依赖,agent就可以对java程序做业务增强,**类似AOP技术,**但是比AOP级别更高,agent属于监控整个java进程。
3.将rpc请求数据 发送给我们的skywalking oapservice接口项目,
4.连接到我们的skywalking webapp项目展示数据,
5.数据最终是可以持久化存放在 db或者es中。
-- SkyWalking 默认是将数据存入在内存中,如果重启SkyWalking 数据则都会丢失。
3、skywalking 环境安装
- 下载apache-skywalking-apm-6.5.0.tar安装包,下载链接:百度网盘 skywalking.tar
1.1. 下载数据库链接:百度网盘 mysql-connector-java-8.0.16.jar后续做数据持久化会用到。
- 进入到bin目录(Windows直接双击启动startup.bat / Linix则执行startup.sh)
注:启动startup.bat = 同时启动oapService.bat 和 webappService.bat
- 查看webapp管理界面 http://127.0.0.1:8080
4、skywalking-agent监控springboot.jar包
-
创建一个springboot项目,并打成jar包
-
启动springboot.jar包时指定agent目录下的skywalking-agent.jar,注意skywalking-agent.jar要写绝对路径
启动jar包命令: java -javaagent:skywalking-agent.jar -jar springboot.jar
启动jar包命令,同时设置服务名称为server-member:java -javaagent:skywalking-agent.jar
-Dskywalking.agent.service_name=server-member -jar springboot.jar
4、测试访问几次接口,然后去SkyWalking控制台 http://127.0.0.1:8080/ 查看效果。
4.1、如何在IDEA中使用skywalking
IDEA启动配置:
-javaagent:D:\java\dev-tool\skywalking\apache-skywalking-apm-6.5.0\apache-skywalking-apm-bin\agent\skywalking-agent.jar
-Dskywalking.agent.service_name=server-member
-Dskywalking.collector.backend_service=127.0.0.1:11800
IDEA启动服务后,调用接口,然后进入WEB页面查看效果:
5、SkyWalking获取全局追踪id
cobol
*
<dependency
>
*
<groupId
>org.apache.skywalking
<
/groupId
>
*
<artifactId
>apm-toolkit-trace
<
/artifactId
>
*
<version
>
6.5.0
<
/version
>
*
<
/dependency
>
获取 TraceContext.traceId();
java
*
*
@RequestMapping("/member")
*
public String
orderToMember
(@RequestParam("id") Integer id) {
*
// 获取request对象
*
HttpServletRequest
request
= ((ServletRequestAttributes)
*
RequestContextHolder.getRequestAttributes()).getRequest();
*
getHeders(request);
*
// 获取traceId
*
String
traceId
= TraceContext.traceId();
*
log.info(
">>traceId:{}<<", traceId);
*
Integer
j
=
1 / id;
*
return
"我是会员服务:" + traceId +
"," + j;
*
}
*
*
public
static
void
getHeders
(HttpServletRequest request) {
*
//2.获得所有头的名称
*
Enumeration<String> headerNames = request.getHeaderNames();
*
while (headerNames.hasMoreElements()) {
//判断是否还有下一个元素
*
String
nextElement
= headerNames.nextElement();
//获取headerNames集合中的请求头
*
String
header2
= request.getHeader(nextElement);
//通过请求头得到请求内容
*
log.info(
"请求头=========={}" + nextElement +
"VALUE:" + header2);
*
//System.out.println(nextElement+":"+header2);
*
}
*
}
6、SkyWalking告警功能
SkyWalking 告警功能是在6.x版本新增的,其核心由一组规则驱动,这些规则定义在SkyWalking目录的config/alarm-settings.yml文件中。
SkyWalking告警后会调用开发者自己定义的接口,
注:自定义的接口地址配置到alarm-settings.yml的webhooks下,当SkyWalking产生告警后会调用webhooks下的URL地址传入告警信息;
alarm-settings.yml文件预先定义了一些常用的告警规则。如下:
1.过去3分钟内服务平均响应时间超过1秒
2.服务成功率在过去2分钟内低于80%
3.服务90%响应时间在过去3分钟内低于1000毫秒
4.服务实例在过去2分钟内的平均响应时间超过1秒
5.端点平均响应时间过去2分钟超过1秒
6.1、自定义告警接口接收数据格式
java
*
[{
*
"scopeId":
1,
*
"scope":
"SERVICE",
*
"name":
"serviceA",
*
"id0":
12,
*
"id1":
0,
*
"ruleName":
"service_resp_time_rule",
*
"alarmMessage":
"alarmMessage xxxx",
*
"startTime":
1560524171000
*
}, {
*
"scopeId":
1,
*
"scope":
"SERVICE",
*
"name":
"serviceB",
*
"id0":
23,
*
"id1":
0,
*
"ruleName":
"service_resp_time_rule",
*
"alarmMessage":
"alarmMessage yyy",
*
"startTime":
1560524171000
*
}]
![](https://file.jishuzhan.net/article/1694231461915267074/8485dcc8f6594c42a38eeea455200052.png)
scopeId、scope:所有可用的 Scope 详见
org.apache.skywalking.oap.server.core.source.DefaultScopeDefine
name:目标 Scope 的实体名称
id0:Scope 实体的 ID
id1:保留字段,目前暂未使用
ruleName:告警规则名称
alarmMessage:告警消息内容
startTime:告警时间,格式为时间戳
6.2、 编写告警接口
6.2.1、封装报警参数的对象
java
*
/**
*
* 封装报警参数的对象
*
*/
*
*
public
class
AlarmMessageDto {
*
private
int scopeId;
*
private String name;
*
private
int id0;
*
private
int id1;
*
private String alarmMessage;
*
private
long startTime;
*
*
public
int
getScopeId
() {
*
return scopeId;
*
}
*
*
public String
getName
() {
*
return name;
*
}
*
*
public
int
getId0
() {
*
return id0;
*
}
*
*
public
int
getId1
() {
*
return id1;
*
}
*
*
public String
getAlarmMessage
() {
*
return alarmMessage;
*
}
*
*
public
long
getStartTime
() {
*
return startTime;
*
}
*
*
public
void
setScopeId
(int scopeId) {
*
this.scopeId = scopeId;
*
}
*
*
public
void
setName
(String name) {
*
this.name = name;
*
}
*
*
public
void
setId0
(int id0) {
*
this.id0 = id0;
*
}
*
*
public
void
setId1
(int id1) {
*
this.id1 = id1;
*
}
*
*
public
void
setAlarmMessage
(String alarmMessage) {
*
this.alarmMessage = alarmMessage;
*
}
*
*
public
void
setStartTime
(long startTime) {
*
this.startTime = startTime;
*
}
*
}
![](https://file.jishuzhan.net/article/1694231461915267074/17c9ede9ba3741c497921132dcc8abd1.png)
6.2.2、提供报警接口
java
*
import com.mayikt.entity.AlarmMessageDto;
*
import org.springframework.web.bind.annotation.RequestBody;
*
import org.springframework.web.bind.annotation.RequestMapping;
*
import org.springframework.web.bind.annotation.RequestMethod;
*
import org.springframework.web.bind.annotation.RestController;
*
*
import java.util.ArrayList;
*
import java.util.List;
*
*
/**
*
* 报警接口
*
*/
*
@RestController
*
public
class
PoliceService {
*
*
private List<List<AlarmMessageDto>> listAlarmMessage =
new
ArrayList<>();
*
*
/**
*
* 接收告警信息
*
*
*
* @param alarmMessageList
*
*/
*
@RequestMapping(value = "/police", method = RequestMethod.POST)
*
public
void
alarm
(@RequestBody List<AlarmMessageDto> alarmMessageList) {
*
listAlarmMessage.add(alarmMessageList);
*
}
*
*
/**
*
* 打印告警信息
*
*
*
* @return
*
*/
*
@RequestMapping("/getListAlarmMessageDto")
*
public List<List<AlarmMessageDto>>
getListAlarmMessageDto
() {
*
return listAlarmMessage;
*
}
*
*
}
![](https://file.jishuzhan.net/article/1694231461915267074/b50e13901f524a45a789bffe077ef494.png)
7、SkyWalking数据持久化
SkyWalking 默认是将数据存入在内存中,如果重启SkyWalking 数据则都会丢失。
我们可以选择将数据持久化存放在mysql、es中等。
1、打开SkyWalking目录config/application.yml,在里边配置Mysql的连接信息;
java
*
storage:
*
selector: ${SW_STORAGE:mysql} #默认使用的H2数据库存储,将h2改为mysql
*
mysql: #修改mysql连接 IP端口号,数据库
*
properties:
*
jdbcUrl: ${SW_JDBC_URL:
"jdbc:mysql://localhost:3306/swtest?serverTimezone=UTC&characterEncoding=utf-8"}
*
dataSource.user: ${SW_DATA_SOURCE_USER:root}
*
dataSource.password: ${SW_DATA_SOURCE_PASSWORD:root@
1234}
*
dataSource.cachePrepStmts: ${SW_DATA_SOURCE_CACHE_PREP_STMTS:
true}
*
dataSource.prepStmtCacheSize: ${SW_DATA_SOURCE_PREP_STMT_CACHE_SQL_SIZE:
250}
*
dataSource.prepStmtCacheSqlLimit: ${SW_DATA_SOURCE_PREP_STMT_CACHE_SQL_LIMIT:
2048}
*
dataSource.useServerPrepStmts: ${SW_DATA_SOURCE_USE_SERVER_PREP_STMTS:
true}
*
metadataQueryMaxSize: ${SW_STORAGE_MYSQL_QUERY_MAX_SIZE:
5000}
2、在oap-libs/目录中放入 mysql-connector-java-8.0.16.jar
3、重启SkyWalking,会自动在配置的Mysql库中创建依赖的表结构。