Sentinel Dashboard 交互最核心的内容,拿下!

👈👈👈 欢迎点赞收藏关注哟

首先分享之前的所有文章 >>>> 😜😜😜
文章合集 : 🎁 juejin.cn/post/694164...
Github : 👉 github.com/black-ant
CASE 备份 : 👉 gitee.com/antblack/ca...

一. 前言

Sentinel 数据交互是集群环境中非常重要的一环。

之前已经了解了 Sentinel 的核心拦截逻辑以及 Dashboard 的原理。这一篇来了解下 Sentinel 集群见交互的流程。

Dashboard 使用

这里演示通过源码运行 Dashboard ,启动命令如下 :

java 复制代码
-Dserver.port=8080 -Dcsp.sentinel.dashboard.server=localhost:8080 -Dproject.name=sentinel-dashboard
  • S1 : 可以监控到当前应用的实时监控 , 意味着 Client 和 Dashboard 有实时交互
  • S2 : 可以查看到当前配置的流控信息,这个配置信息是从 Client 端拿到的

二. 原理解析

那么基于上面的案例,我们能明确的知道, Client 和 Dashboard 一定是有交互的,那么这个过程是怎么实现的呢?

👉 直接上原理 ,应付面试看这个就完事了

  • S1 : Sentinel 通过心跳上报自己的存在 -- SimpleHttpHeartbeatSender
  • S2 : Dashboard 接到请求后 , 拿到 Client 的 IP 和 端口号 存入 Map
  • S3 : Dashboard 基于端口信息 与 Client 会建立 Socket 连接 ,Dashboard 定时查询 Client 的各项信息 (Client 保存信息到 file 文件中)
  • S4 : Dashboard 保存信息到 Memory 内存 中

2.1 第一步 : 心跳流程

心跳流程的核心类为 :SimpleHttpHeartbeatSender ,在这个类中会发起一个 Http 请求到 Dashboard ,请求的接口为 : /registry/machine

java 复制代码
// 1. 获取配置信息
public class TransportConfig {
    public static final String HEARTBEAT_DEFAULT_PATH = "/registry/machine";
}
C- TransportConfig # getHeartbeatApiPath


// 2. 发起 Http 请求
SimpleHttpRequest request = new SimpleHttpRequest(addrInfo, TransportConfig.getHeartbeatApiPath());
// --- 没什么东西,主要是版本以及当前开启的 Socket 端口 
request.setParams(heartBeat.generateCurrentMessage());
SimpleHttpResponse response = httpClient.post(request);

2.2 第二步 : Dashboard 接收到心跳

上面看到实际上会 HTTP 调用接口 ,调用到的是 MachineRegistryController 类, 看名字就知道,这个是用来注册机器节点的。

当调用到接口后 , 会保存这些信息 :

然后首先传递到 AppManagement ,再传递到 MachineDiscovery (SimpleMachineDiscovery),最终存储到一个 Map 中

java 复制代码
private final ConcurrentMap<String, AppInfo> apps = new ConcurrentHashMap<>();

2.3 第三步 : Client 存储访问信息

Sentinel 主要是本机单机运行的,他会将自己的流控信息存储到本地把配置发送到数据源 (Zookeeper 等)。

❓ 这里面总共涉及到3个核心的类 :

  • MetricWriter :用于写入指标数据的类。它提供了一些方法来将指标数据写入到指定的存储后端中
  • MetricsReader : 从指定的数据源读取指标文件
  • MetricSearcher : 从指定目录下找出所有的metric文件,并按照指定时间戳进行检索

📂 查找的路径如下 : C:\USER\logs\csp\service-metrics.log ,内容大致如下 :

java 复制代码
1700483124000|2023-11-20 20:25:24|HelloWorld|224342|0|224341|0|0|0|0|0
1700483125000|2023-11-20 20:25:25|HelloWorld|75658|0|75659|0|0|0|0|0

关于内容和意义这里就不深入了,意义不大。

2.4 第四步 : Client 端建立 Socket 连接

  • 👉 1. 首先通过 SimpleHttpCommandCenter 建立连接 Socket
java 复制代码
// 这里的端口就是之前上报 Dashboard 的端口
ServerSocket serverSocket = getServerSocketFromBasePort(port);
// 这里可以看出是通过一个线程池开启的 Socket 监听流程
executor.submit(new ServerThread(serverSocket));
  • 👉 2. 开启 Socket 后通过 HttpEventTask 进行持续的监听 : ServerThread
java 复制代码
while (true) {
    // 一直保持接收
    socket = this.serverSocket.accept();
    HttpEventTask eventTask = new HttpEventTask(socket);
    bizExecutor.submit(eventTask);
}
  • 👉 3. 接收到 Command 的情况下调用对应的 Handler 处理 : HttpEventTask
java 复制代码
// 通过  commandName 拿到对应的 Handler 
CommandHandler<?> commandHandler = SimpleHttpCommandCenter.getHandler(commandName);
// 处理 Handler 后生成对应的 Command 
CommandResponse<?> response = commandHandler.handle(request);
// 返回结果
handleResponse(response, printWriter);         
  • 👉 4. 调用 第三步的 Search 方法进行查询,查询到监控日志 : SendMetricCommandHandler
java 复制代码
- 请求对象中会传递 startTime 和 endTime 进来,Client 就是基于这些参数进行查询
String startTimeStr = request.getParam("startTime");
String endTimeStr = request.getParam("endTime");
String maxLinesStr = request.getParam("maxLines");
String identity = request.getParam("identity");

// 查询第三步的日志记录
list = searcher.findByTimeAndResource(startTime, endTime, identity);
   

到这里 Client 端接收的流程就很清楚了,剩下的就是 Dashboard 的调用流程了!!

2.5 第五步 : 最重要的 Dashboard 请求数据查询

  • 前面已经知道了 ,Dashboard 知道了 Client 的 IP 和开启 Socket 的端口
  • Client 已经保存了当前的流控状态信息

这段逻辑的核心代码在 MetricFetcher 类中 :

  • S1 : 在初始化环节 会 Start() 一个 scheduleAtFixedRate 定时任务进行循环
  • S2 : 在定时任务 中调用 fetchAllApp 进行全量读取
  • S3 : 通过 AppManagement (第二步接收到的心跳数据)拿到所有的节点 App 信息
  • S4 : 调用 MetricFetcher # doFetchAppMetric 开始抓取指标信息
java 复制代码
final String url = "http://" + machine.getIp() + ":" + machine.getPort() + "/" + METRIC_URL_PATH
    + "?startTime=" + startTime + "&endTime=" + endTime + "&refetch=" + false;
    
// http://192.168.0.14:8719/metric?startTime=1700484694000&endTime=1700484700000&refetch=false    

👉 当最终拿到结果后,把结果进行处理放入 Map , 最终在 writeMetric 方法存入 MetricsRepository

java 复制代码
// 默认实现是放在内存中 : 
public class InMemoryMetricsRepository implements MetricsRepository<MetricEntity> 

三. 补充知识点

3.1 关于 CommandHandler

CommandHandler 是一个接口,它有大量的实现,每个实现都会有对应的功能,包括规则管理,上面说的数据上报等等

3.2 关于 Rule 的 Fetch

Dashboard 里面还有个重要的类为 :SentinelApiClient ,它主要的目的是与 Client 端关于规则的通信 :

  • S1 : 打开 Dashboard 控制台 , 触发接口调用 /machineResource.json
  • S2 : SentinelApiClient # executeCommand 基于对应的类型调用 Client
java 复制代码
http://192.168.0.14:8719/metric?startTime=1700486200000&endTime=1700486206000&refetch=false

格式和上面的一样,会调用到上面的 Handler, 至此流程全部串通❗❗❗

总结

就说这篇源码分析是不是很清晰吧

我想没看过代码都能了解得很清楚。

完结 🐼🐼🐼

相关推荐
安之若素^7 分钟前
启用不安全的HTTP方法
java·开发语言
ruanjiananquan9913 分钟前
c,c++语言的栈内存、堆内存及任意读写内存
java·c语言·c++
chuanauc40 分钟前
Kubernets K8s 学习
java·学习·kubernetes
一头生产的驴1 小时前
java整合itext pdf实现自定义PDF文件格式导出
java·spring boot·pdf·itextpdf
YuTaoShao1 小时前
【LeetCode 热题 100】73. 矩阵置零——(解法二)空间复杂度 O(1)
java·算法·leetcode·矩阵
zzywxc7871 小时前
AI 正在深度重构软件开发的底层逻辑和全生命周期,从技术演进、流程重构和未来趋势三个维度进行系统性分析
java·大数据·开发语言·人工智能·spring
YuTaoShao3 小时前
【LeetCode 热题 100】56. 合并区间——排序+遍历
java·算法·leetcode·职场和发展
程序员张33 小时前
SpringBoot计时一次请求耗时
java·spring boot·后端
llwszx6 小时前
深入理解Java锁原理(一):偏向锁的设计原理与性能优化
java·spring··偏向锁
云泽野7 小时前
【Java|集合类】list遍历的6种方式
java·python·list