在上文中,我们学习了如何在应用中集成 sentinel,并定义资源,但我们仍需要为资源定义规则。
在应用日常运行过程中,当发现资源需要被限流,在项目中通过代码定义规则、验证、发布,这个过程费时费力,亟需一种更加便捷的运维工具。
sentinel 中提供了单独部署的控制台应用:sentinel dashboard,使得我们可以在浏览器上以图形化的方式对资源规则进行 crud,大大减少了维护的成本。
通信模块
我们将单独部署的 sentinel dashboard 称之为 sentinel server,集成 sentinel 的应用称之为 sentinel client。那 server 和 client 之间怎么通信呢?
server 和 client 之间是通过 http 协议进行通信,client 如果想要搭配 server 使用,需要额外在应用中引入 sentinel-transport 模块用于通信。
transport 模块的实现有三种:
- 基于 java.net.ServerSocket 实现的 sentinel-transport-simple-http 模块
- 基于 Spring MVC 实现的 sentinel-transport-spring-mvc 模块
- 基于 Netty 实现的 sentinel-transport-netty-http 模块
如无特殊要求,一般使用 sentinel-transport-simple-http 即可,我们下文也以此来介绍 server 和 client 之间的通信原理。
客户端发现
在开始的开始之前,我们有个问题,server 是如何发现 client 的呢?是借助于 zookeeper 进行的服务发现嘛?还是其他的类似机制?
倒也没那么复杂,sentinel 没有借助额外的组件来实现服务发现。只需 client 启动时加入几个 JVM 参数,就可将 client 当前的机器信息上报给 server:
-Dcsp.sentinel.dashboard.server=consoleIp:port
指定控制台地址和端口-Dproject.name client
项目名称-Dcsp.sentinel.api.port=xxxx
如果一台机器上部署了多个 client,为了防止端口冲突,可以自行指定 client 和 server 通信的端口(选填)
那么它是怎么上报的?何时上报的呢?
心跳机制
在 client 中,当进入资源时,sentinel 会触发一系列初始化动作,其中就有 HeartbeatSender 的初始化(在 sentinel扩展章节有介绍)。HeartbeatSender 在初始化之后,会定时向 csp.sentinel.dashboard.server
地址发送心跳,心跳信息里包含当前机器 ip、port、sentinel 版本等信息。
server 接收到了心跳信息,会将心跳信息中的机器信息添加到列表中,并记录最后一次心跳时间(如果最后心跳时间距今超过 30s,则标记 client 失联)。
事件通知
好了,现在 server 也发现 client 了。那如果我在 server 进行了规则的修改,client 是如何感知到并修改当前服务的规则呢?
我们通过下面的流程图来了解规则从浏览器修改到 client 内部规则更新的整个过程:
根据上图我们可以看到核心部分就是根据请求的 commandName 找到对应的 handler。
在 sentinel 中会通过 SPI 机制找到所有的 CommandHandler 实现类,然后通过解析类上的 @CommandMapping 注解获取 commandName 和 handler 的对应关系。
数据拉取
在了解了 server 如何发现 client 以及 server 如何将事件推送到 client 之后。接下来我们来了解下 server 如何主动从 client 中拉取数据的。
为了能够在 dashboard 中查看客户端的实时调用、配置规则等信息,server 中需要主动拉取 client 的以下几种信息:
- 「实时监控」页面的监控统计信息
- 「簇点链路」页面的调用链路信息
- 各个规则模块的配置规则信息
如何拉取监控信息
- 浏览器调用
/metric/queryTopResourceMetric.json
接口,从InMemoryMetricsRepository
获取 metrics 数据 InMemoryMetricsRepository
数据由MetricFetcher
定时从 client 中拉取- client 内部的 metrics 存储于文件中,通过
MetricSearcher
可以按照时间进行检索(metrics 具体写入、查询逻辑后续章节会介绍))
如何拉取链路信息
- 浏览器调用
/resource/machineResource.json
接口,通过SentinelApiClient
从 client 拉取数据 - client 从
Constants.ROOT
拉取链路信息或从ClusterBuilderSlot#clusterNodeMap
拉取资源
如何获取规则等信息
- 浏览器调用
/v1/flow/rules
接口,通过SentinelApiClient
从 client 拉取规则数据 - client 从对应的
RuleManager
(如:FlowRuleManager
)获取规则数据
总结
本章我们学习了 sentinel dashboard(server) 如何搭配 sentinel 的业务应用(client)使用,并介绍了 server 和 client 之间的底层通信行为,其大致可分为三种:
- client 通过心跳机制,使得 server 发现 client 并记录
- server 在发生规则变更时,会发送事件请求到 client,client 内部通过 commandName 的分发来处理对应的事件
- server 会以定时、实时的方式通过 http 请求从 client 拉取数据,从而在 dashboard 中实时展示客户端请求等信息