Sentinel指标数据传输过程简述:从流量控制到控制台实时展示

背景

我们最近发现一个问题,线上的应用在接入Sentinel后,在Sentinel Dashboard中能看到机器列表中的实例都处于健康状态,但是实时监控中却没有任何数据,因此为了排查问题,初步了解了Sentinel客户端与Dashboard之间是如何传输监控数据的。

启动Dashboard

Sentinel Dashboard是一个独立的web服务,有一套可视化界面用于监控和管理其他接入Sentinel的应用,默认启动端口为8080。

客户端接入

1. 引入依赖

一个应用如果要接入Sentinel,需接入sentinel-core包,用于实现核心流控功能。
而想要接入Dashboard并与之通信则需要引入transport组件,Sentinel提供了两种选择:

  • sentinel-transport-simple-http:基于jdk net包实现的,通过http协议传输数据
  • sentinel-transport-netty-http:在netty的基础上实现,通过http协议传输数据
<dependency>
    <groupId>com.alibaba.cspgroupId>
    <artifactId>sentinel-transport-simple-httpartifactId>
    <version>${sentinel.version}version>
dependency>
<dependency>
    <groupId>com.alibaba.cspgroupId>
    <artifactId>sentinel-transport-netty-httpartifactId>
    <version>${sentinel.version}version>
dependency>

这两个组件任选其一即可,它们的区别只在于通信协议的实现方式,功能没有区别,一般推荐使用sentinel-transport-netty-http(下文以此为例)

2. 设定启动参数

只使用基本的流控功能的话,是不用额外指定启动参数的。但如果要接入Dashboard进行实时监控,则需要在应用启动时加入 JVM 参数 -Dcsp.sentinel.dashboard.server=ip:port 指定控制台地址和端口。

其他相关参数有:

配置项 默认值 描述
csp.sentinel.dashboard.server localhost:8080 dashboard服务的地址,用于传输通信
csp.sentinel.heartbeat.client.ip 手动配置应用的ip,如无则自动获取
csp.sentinel.api.port 8719 应用用于传输数据的端口
project.name 应用显示的名称

3. 保存指标数据

接入Sentinel并使用流控功能对相关资源请求进行了拦截处理后,资源请求的相关指标(qps、通过请求数、拒绝请求数等)会以两种形式保存在应用端:

  • 内存:将统计数据保存在类的静态属性中
    • 比如:ClusterBuilderSlotclusterNodeMap保存了窗口时间内所有簇节点数据
  • 文件:通过日志文件的形式记录指标数据
    • 比如实时统计日志会在一个 叫 xx-metrics.log.${date} 的文件中记录下来

4. 启动传输组件(transport)

4.1 上报心跳

sentinel-transport-netty-http为例,当Sentinel核心组件初始后,通过Spi扩展加载机制,HttpHeartbeatSender.java会初始化一个定时任务,不断向csp.sentinel.dashboard.server指定的Dashboard服务地址发送心跳信息。

此时应用实例信息即会出现在Dashboard界面的机器列表中。

4.2 启动http服务

同样基于Spi扩展加载机制,NettyHttpCommandCenter.java会启动一个netty server,并监听csp.sentinel.api.port配置的端口(默认8719),后面所有的监控数据都将通过此端口传输。

4.3 注册CommandHandler

当通信服务启动成功后,会注册一系列CommandHandler,用于处理数据传输的请求,每个CommandHandler都与特定url绑定,相当于提供出去的接口。

所有的CommandHandler都在sentinel-transport-common模块的com.alibaba.csp.sentinel.command.handler包下:

Sentinel指标数据传输过程简述:从流量控制到控制台实时展示_第1张图片

CommandHandler对应的url和功能通过注解@CommandMapping指定。

  • 比如ApiCommandHandler,相当于接口菜单,请求http://localhost:8719/api,即可返回所有可用的CommandHandler的请求url和其功能说明:
    Sentinel指标数据传输过程简述:从流量控制到控制台实时展示_第2张图片
    Sentinel指标数据传输过程简述:从流量控制到控制台实时展示_第3张图片

而主要用于返回监控指标数据的接口/metric对应的是SendMetricCommandHandler,在处理数据请求时,是通过MetricSearcher类,去日志文件中查找相应时间范围的历史数据。

监控数据传输及展示

1. 轮询和保存指标数据

经过上述过程,应用已经与Dashboard服务建立了连接,Dashboard服务中,有一个名为MetricFetcher的类,会不断获取各个应用实例的指标数据,方法调用:

MetricFetcher.fetchAllApp();

┆┈ MetricFetcher.doFetchAppMetric();

┆┈┈┈ MetricFetcher.fetchOnce();

fetchOnce()中其实就是组装了一个请求url,向http://ip:port/metric接口发送http请求。

应用返回的指标数据,就会被存储到MetricsRepository中:

MetricFetcher.writeMetric();

┆┈ MetricsRepository.saveAll();

2. 界面展示

应用的监控指标数据已经保存到Dashboard了,这个时候,我们在控制台界面来查看监控数据:

  • Sentinel指标数据传输过程简述:从流量控制到控制台实时展示_第4张图片

可以看到,页面会不断轮询Dashboard后端的/queryTopResourceMetric.json接口,此接口由MetricController提供:

MetricController.queryTopResourceMetric();

┆┈ MetricsRepository.queryByAppAndResourceBetween();

这里,就会去MetricsRepository中查询之前保存的指标数据。

总结

至此整个Sentinel客户端(应用)与控制台之间传输监控数据的流程就全部完成,总结一下,就是两部分内容:

  1. 应用产生并缓存监控数据,上报心跳到Dashboard,并提供http接口
  2. Dashboard轮询应用接口,保存监控数据,展示到前端界面

希望这篇文章能给大家带来帮助,篇幅有限,很多细节的地方没有涉及到,建议可以通过Sentinel项目的源码深入学习,不管是对于问题排查,还是代码学习,都有很大的帮助。

你可能感兴趣的:(sentinel)