当前位置: 首页 > news >正文

Sentinel 监控数据持久化(mysql)

Sentinel 实时监控仅存储 5 分钟以内的数据,如果需要持久化,需要通过调用实时监控接口来定制,即自行扩展实现 MetricsRepository 接口(修改 控制台源码)。

本文通过使用Mysql持久化监控数据。

1.构建存储表(mysql)

CREATE TABLE `sentinel_metric` (`id` INT NOT NULL AUTO_INCREMENT COMMENT 'id,主键',`gmt_create` DATETIME COMMENT '创建时间',`gmt_modified` DATETIME COMMENT '修改时间',`app` VARCHAR(100) COMMENT '应用名称',`timestamp` DATETIME COMMENT '统计时间',`resource` VARCHAR(500) COMMENT '资源名称',`pass_qps` INT COMMENT '通过qps',`success_qps` INT COMMENT '成功qps',`block_qps` INT COMMENT '限流qps:拒绝的qps',`exception_qps` INT COMMENT '发送异常的次数',`rt` DOUBLE COMMENT '所有successQps的rt的和,单位ms; 控制台响应时间(平均响应时间)=rt/success_qps',`count` INT COMMENT '本次聚合的总条数: 集群的服务数量',`resource_code` INT COMMENT '资源的hashCode',INDEX app_idx(`app`) USING BTREE,INDEX timestamp_idx(`timestamp`) USING BTREE,PRIMARY KEY (`id`)
) ENGINE=INNODB DEFAULT CHARSET=utf8;

2.修改控制台源码

2.1 添加Maven依赖

        <!-- mysql db --><dependency><groupId>mysql</groupId><artifactId>mysql-connector-java</artifactId><version>8.0.25</version></dependency><dependency><groupId>com.baomidou</groupId><artifactId>mybatis-plus-boot-starter</artifactId><version>3.5.1</version></dependency>

2.2 修改配置文件

spring.datasource.url=jdbc:mysql://127.0.0.1:3306/xx?useUnicode=true&characterEncoding=UTF-8
spring.datasource.username=xx
spring.datasource.password=xxxxx
spring.datasource.driver-class=com.mysql.cj.jdbc.Driver

2.3 逆向代码生成(新增)

参考:Springboot入门之Mybatis逆向工程_Ocean@上源码的博客-CSDN博客

package com.alibaba.csp.sentinel.dashboard.metric.dao;import com.alibaba.csp.sentinel.dashboard.datasource.entity.MetricEntity;
import com.baomidou.mybatisplus.annotation.IdType;
import com.baomidou.mybatisplus.annotation.TableField;
import com.baomidou.mybatisplus.annotation.TableId;
import com.baomidou.mybatisplus.annotation.TableName;import java.util.Date;@TableName("sentinel_metric")
public class Metric {/*** 主键ID*/@TableId(value = "id", type = IdType.INPUT)private Long id;/*** 创建时间*/@TableField("gmt_create")private Date gmtCreate;/*** 修改时间*/@TableField("gmt_modified")private Date gmtModified;/*** 应用名称*/private String app;/*** 监控信息的时间戳*/private Date timestamp;/*** 资源名*/private String resource;/*** 通过qps*/@TableField("pass_qps")private Long passQps;/*** 成功qps*/@TableField("success_qps")private Long successQps;/*** 限流qps*/@TableField("block_qps")private Long blockQps;/*** 异常qps*/@TableField("exception_qps")private Long exceptionQps;/*** 所有successQps的rt的和*/private Double rt;/*** 本次聚合的总条数*/private Integer count;/*** 资源的hashCode*/@TableField("resource_code")private Integer resourceCode;public Metric(MetricEntity metric) {this.id = metric.getId();this.gmtCreate = metric.getGmtCreate();this.gmtModified = metric.getGmtModified();this.app = metric.getApp();this.timestamp = metric.getTimestamp();this.resource = metric.getResource();this.passQps = metric.getPassQps();this.successQps = metric.getSuccessQps();this.blockQps = metric.getBlockQps();this.exceptionQps = metric.getExceptionQps();this.rt = metric.getRt();this.count = metric.getCount();this.resourceCode = metric.getResourceCode();}public Metric() {}public Long getId() {return id;}public void setId(Long id) {this.id = id;}public Date getGmtCreate() {return gmtCreate;}public void setGmtCreate(Date gmtCreate) {this.gmtCreate = gmtCreate;}public Date getGmtModified() {return gmtModified;}public void setGmtModified(Date gmtModified) {this.gmtModified = gmtModified;}public String getApp() {return app;}public void setApp(String app) {this.app = app;}public Date getTimestamp() {return timestamp;}public void setTimestamp(Date timestamp) {this.timestamp = timestamp;}public String getResource() {return resource;}public void setResource(String resource) {this.resource = resource;}public Long getPassQps() {return passQps;}public void setPassQps(Long passQps) {this.passQps = passQps;}public Long getSuccessQps() {return successQps;}public void setSuccessQps(Long successQps) {this.successQps = successQps;}public Long getBlockQps() {return blockQps;}public void setBlockQps(Long blockQps) {this.blockQps = blockQps;}public Long getExceptionQps() {return exceptionQps;}public void setExceptionQps(Long exceptionQps) {this.exceptionQps = exceptionQps;}public Double getRt() {return rt;}public void setRt(Double rt) {this.rt = rt;}public Integer getCount() {return count;}public void setCount(Integer count) {this.count = count;}public Integer getResourceCode() {return resourceCode;}public void setResourceCode(Integer resourceCode) {this.resourceCode = resourceCode;}@Overridepublic String toString() {return "SentinelMetricsEntity{" +"id=" + id +", gmtCreate=" + gmtCreate +", gmtModified=" + gmtModified +", app='" + app + '\'' +", timestamp=" + timestamp +", resource='" + resource + '\'' +", passQps=" + passQps +", successQps=" + successQps +", blockQps=" + blockQps +", exceptionQps=" + exceptionQps +", rt=" + rt +", count=" + count +", resourceCode=" + resourceCode +'}';}}
package com.alibaba.csp.sentinel.dashboard.metric.dao;import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import org.apache.ibatis.annotations.Mapper;@Mapper
public interface MetricMapper extends BaseMapper<Metric> {}
package com.alibaba.csp.sentinel.dashboard.metric.service;import com.alibaba.csp.sentinel.dashboard.datasource.entity.MetricEntity;
import com.alibaba.csp.sentinel.dashboard.metric.dao.Metric;
import com.baomidou.mybatisplus.extension.service.IService;import java.util.Collection;
import java.util.List;/*** <p>* 服务类* </p>** @author ocean* @since 2023-05-21*/
public interface MetricService extends IService<Metric> {List<String> listResourcesOfApp(String app);List<MetricEntity> queryByAppAndResourceBetween(String app, String resource, Long startTime, Long endTime);void saveAll(Iterable<MetricEntity> metrics);}
package com.alibaba.csp.sentinel.dashboard.metric.service.impl;import com.alibaba.csp.sentinel.dashboard.datasource.entity.MetricEntity;
import com.alibaba.csp.sentinel.dashboard.metric.dao.Metric;
import com.alibaba.csp.sentinel.dashboard.metric.dao.MetricMapper;
import com.alibaba.csp.sentinel.dashboard.metric.service.MetricService;
import com.alibaba.csp.sentinel.util.StringUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.google.common.collect.Lists;
import org.springframework.stereotype.Service;import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.stream.Collectors;@Service
public class MetricServiceImpl extends ServiceImpl<MetricMapper, Metric> implements MetricService {private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();@Overridepublic void saveAll(Iterable<MetricEntity> metrics) {if (metrics == null) {return;}readWriteLock.writeLock().lock();try {List<Metric> metricList = Lists.newArrayList();metrics.forEach(data -> {metricList.add(new Metric(data));});this.saveBatch(metricList);} finally {readWriteLock.writeLock().unlock();}}@Overridepublic List<String> listResourcesOfApp(String app) {List<String> results = new ArrayList<>();if (StringUtil.isBlank(app)) {return results;}readWriteLock.readLock().lock();try {LambdaQueryWrapper<Metric> metricLambdaQueryWrapper = Wrappers.lambdaQuery(Metric.class).eq(Metric::getApp, app).orderByAsc(Metric::getTimestamp);return this.list(metricLambdaQueryWrapper).stream().map(Metric::getResource).collect(Collectors.toList());} finally {readWriteLock.readLock().unlock();}}@Overridepublic List<MetricEntity> queryByAppAndResourceBetween(String app, String resource, Long startTime, Long endTime) {List<MetricEntity> results = new ArrayList<>();if (StringUtil.isBlank(app)) {return results;}readWriteLock.readLock().lock();try {LambdaQueryWrapper<Metric> metricLambdaQueryWrapper = Wrappers.lambdaQuery(Metric.class).eq(Metric::getApp, app).eq(Metric::getResource, resource).ge(Metric::getTimestamp, new Date(startTime)).le(Metric::getTimestamp, new Date(endTime)).orderByAsc(Metric::getTimestamp);List<Metric> metricList = this.list(metricLambdaQueryWrapper);return metricList.stream().map(MetricEntity::new).collect(Collectors.toList());} finally {readWriteLock.readLock().unlock();}}
}

2.4 修改源码

2.4.1 MetricController

修改统计时长修改如下标记处代码: 

2.4.2 MetricFetcher

3. 验证查询数据库

相关文章:

Sentinel 监控数据持久化(mysql)

Sentinel 实时监控仅存储 5 分钟以内的数据&#xff0c;如果需要持久化&#xff0c;需要通过调用实时监控接口来定制&#xff0c;即自行扩展实现 MetricsRepository 接口&#xff08;修改 控制台源码&#xff09;。 本文通过使用Mysql持久化监控数据。 1.构建存储表&#xff08…...

基于法医调查算法优化概率神经网络PNN的分类预测 - 附代码

基于法医调查算法优化概率神经网络PNN的分类预测 - 附代码 文章目录 基于法医调查算法优化概率神经网络PNN的分类预测 - 附代码1.PNN网络概述2.变压器故障诊街系统相关背景2.1 模型建立 3.基于法医调查优化的PNN网络5.测试结果6.参考文献7.Matlab代码 摘要&#xff1a;针对PNN神…...

canvas高级动画001:文字瀑布流

canvas实例应用100 专栏提供canvas的基础知识&#xff0c;高级动画&#xff0c;相关应用扩展等信息。 canvas作为html的一部分&#xff0c;是图像图标地图可视化的一个重要的基础&#xff0c;学好了canvas&#xff0c;在其他的一些应用上将会起到非常重要的帮助。 文章目录 示例…...

抽象类, 接口, Object类 ---java

目录 一. 抽象类 1.1 抽象类概念 1.2 抽象类语法 1.3 抽象类特性 1.4 抽象类的作用 二. 接口 2.1 接口的概念 2.2 语法规则 2.3 接口的使用 2.4 接口间的继承 2.5 抽象类和接口的区别 三. Object类 3.1 toString() 方法 3.2 对象比较equals()方法 3.3 hash…...

SOAP 协议和 HTTP 协议:深入解读与对比

SOAP 和 HTTP 协议 SOAP 协议 SOAP&#xff08; Simple Object Access Protocol&#xff09;是一种用于在节点之间交换结构化数据的网络协议。它使用XML格式来传输消息。它在 HTML 和 SMTP 等应用层协议的基础上进行标记和传输。SOAP 允许进程在整个平台、语言和操作系统中进…...

Unity发布IOS后,使用xcode打包报错:MapFileParser.sh:Permissiondenied

1.错误提示 使用xcode打包错误提示&#xff1a;/Users/mymac/Desktop/myproject/MapFileParser.sh: Permission denied 2.解决方案 打开控制台输入&#xff1a;chmod ax /Users/mymac/Desktop/myproject/MapFileParser.sh。按回车键执行&#xff0c;然后重新使用xcode发布程序…...

2021年12月 Scratch(三级)真题解析#中国电子学会#全国青少年软件编程等级考试

Scratch等级考试(1~4级)全部真题・点这里 一、单选题(共25题,每题2分,共50分) 第1题 执行下列程序,屏幕上可以看到几只小猫? A:1 B:3 C:4 D:0 答案:B 第2题 下列程序哪个可以实现:按下空格键,播放完音乐后说“你好!”2秒? A: B: C:...

mac上Homebrew的安装与使用

打开终端&#xff1a;command空格 &#xff0c;搜索‘’终端 ’&#xff0c;打开终端 在终端中输入以下命令并按下回车键&#xff1a; /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"这个命令会自动下载并安装…...

YOLOv5 分类模型 预处理 OpenCV实现

YOLOv5 分类模型 预处理 OpenCV实现 flyfish YOLOv5 分类模型 预处理 PIL 实现 YOLOv5 分类模型 OpenCV和PIL两者实现预处理的差异 YOLOv5 分类模型 数据集加载 1 样本处理 YOLOv5 分类模型 数据集加载 2 切片处理 YOLOv5 分类模型 数据集加载 3 自定义类别 YOLOv5 分类模型…...

在arm 64 环境下使用halcon算法

背景&#xff1a; halcon&#xff0c;机器视觉领域神一样得存在&#xff0c;在windows上&#xff0c;应用得特别多&#xff0c; 但是arm环境下使用得很少。那如何在arm下使用halcon呢。按照官方说明&#xff0c;arm下只提供了运行时环境&#xff0c;并且需要使用价值一万多人民…...

H5(uniapp)中使用echarts

1,安装echarts npm install echarts 2&#xff0c;具体页面 <template><view class"container notice-list"><view><view class"aa" id"main" style"width: 500px; height: 400px;"></view></v…...

QLineEdit设置掩码Ip

目的 有时&#xff0c;用单行编辑框想限制输入&#xff0c;但QLineEdit提供的setInputMask()方法用来限制输入字符或者数字还可以&#xff0c;但要做约束&#xff0c;得和验证器结合。 setInputMash()描述 此属性包含验证输入掩码 如果没有设置掩码&#xff0c;inputMask() …...

开源语音大语言模型来了!阿里基于Qwen-Chat提出Qwen-Audio!

论文链接&#xff1a;https://arxiv.org/pdf/2311.07919.pdf 开源代码&#xff1a;https://github.com/QwenLM/Qwen-Audio 引言 大型语言模型&#xff08;LLMs&#xff09;由于其良好的知识保留能力、复杂的推理和解决问题能力&#xff0c;在通用人工智能&#xff08;AGI&am…...

缓存雪崩、击穿、穿透及解决方案_保证缓存和数据库一致性

文章目录 缓存雪崩、击穿、穿透1.缓存雪崩造成缓存雪崩解决缓存雪崩 2. 缓存击穿造成缓存击穿解决缓存击穿 3.缓存穿透造成缓存穿透解决缓存穿透 更新数据时&#xff0c;如何保证数据库和缓存的一致性&#xff1f;1. 先更新数据库&#xff1f;先更新缓存&#xff1f;解决方案 2…...

仿 美图 / 饿了么,店铺详情页功能

前言 UI有所不同&#xff0c;但功能差不多&#xff0c;商品添加购物车功能 正在写&#xff0c;写完会提交仓库。 效果图一&#xff1a;左右RecyclerView 联动 效果图二&#xff1a;通过点击 向上偏移至最大值 效果图三&#xff1a;通过点击 或 拖动 展开收缩公告 效果图四&…...

Redis Cluster主从模式详解

在软件的架构中&#xff0c;主从模式&#xff08;Master-Slave&#xff09;是使用较多的一种架构。主&#xff08;Master&#xff09;和从&#xff08;Slave&#xff09;分别部署在不同的服务器上&#xff0c;当主节点服务器写入数据时&#xff0c;同时也会将数据同步至从节点服…...

Linux技能篇-非交互式修改密码

今天的文章没有格式&#xff0c;简单分享一个小技能&#xff0c;就是标题所说–非交互式修改密码。 一、普通方式修改用户密码 最普通的修改密码的命令就是passwd命令 [rootlocalhost ~]# passwd root Changing password for user root. New password: Retype new password:…...

记一次docker服务启动失败解决过程

环境&#xff1a;centos 7.6 报错&#xff1a;start request repeated too quickly for docker.service 由于服务器修复了内核漏洞&#xff0c;需要重启&#xff0c;没想到重启后&#xff0c;docker启动失败了 查看状态 systemctl status docker如下图 里面有一行提示&…...

npm ERR! node-sass@4.13.0 postinstall: `node scripts/build.js`

npm ERR! node-sass4.13.0 postinstall: node scripts/build.js npm config set sass_binary_sitehttps://npm.taobao.org/mirrors/node-sass npm install npm run dev Microsoft Windows [版本 10.0.19045.2965] (c) Microsoft Corporation。保留所有权利。C:\Users\Administr…...

Java定时任务 ScheduledThreadPoolExecutor

ScheduledThreadPoolExecutor 的创建 ScheduledThreadPoolExecutor executorService new ScheduledThreadPoolExecutor(1, // 核心线程数new BasicThreadFactory.Builder().namingPattern("example-schedule-pool-%d") // 线程命名规则.daemon(true) // 设置线程为…...

Unity3D中Gfx.WaitForPresent优化方案

前言 在Unity中&#xff0c;Gfx.WaitForPresent占用CPU过高通常表示主线程在等待GPU完成渲染&#xff08;即CPU被阻塞&#xff09;&#xff0c;这表明存在GPU瓶颈或垂直同步/帧率设置问题。以下是系统的优化方案&#xff1a; 对惹&#xff0c;这里有一个游戏开发交流小组&…...

工业安全零事故的智能守护者:一体化AI智能安防平台

前言&#xff1a; 通过AI视觉技术&#xff0c;为船厂提供全面的安全监控解决方案&#xff0c;涵盖交通违规检测、起重机轨道安全、非法入侵检测、盗窃防范、安全规范执行监控等多个方面&#xff0c;能够实现对应负责人反馈机制&#xff0c;并最终实现数据的统计报表。提升船厂…...

【HarmonyOS 5.0】DevEco Testing:鸿蒙应用质量保障的终极武器

——全方位测试解决方案与代码实战 一、工具定位与核心能力 DevEco Testing是HarmonyOS官方推出的​​一体化测试平台​​&#xff0c;覆盖应用全生命周期测试需求&#xff0c;主要提供五大核心能力&#xff1a; ​​测试类型​​​​检测目标​​​​关键指标​​功能体验基…...

蓝桥杯 2024 15届国赛 A组 儿童节快乐

P10576 [蓝桥杯 2024 国 A] 儿童节快乐 题目描述 五彩斑斓的气球在蓝天下悠然飘荡&#xff0c;轻快的音乐在耳边持续回荡&#xff0c;小朋友们手牵着手一同畅快欢笑。在这样一片安乐祥和的氛围下&#xff0c;六一来了。 今天是六一儿童节&#xff0c;小蓝老师为了让大家在节…...

剑指offer20_链表中环的入口节点

链表中环的入口节点 给定一个链表&#xff0c;若其中包含环&#xff0c;则输出环的入口节点。 若其中不包含环&#xff0c;则输出null。 数据范围 节点 val 值取值范围 [ 1 , 1000 ] [1,1000] [1,1000]。 节点 val 值各不相同。 链表长度 [ 0 , 500 ] [0,500] [0,500]。 …...

Python爬虫(二):爬虫完整流程

爬虫完整流程详解&#xff08;7大核心步骤实战技巧&#xff09; 一、爬虫完整工作流程 以下是爬虫开发的完整流程&#xff0c;我将结合具体技术点和实战经验展开说明&#xff1a; 1. 目标分析与前期准备 网站技术分析&#xff1a; 使用浏览器开发者工具&#xff08;F12&…...

ABAP设计模式之---“简单设计原则(Simple Design)”

“Simple Design”&#xff08;简单设计&#xff09;是软件开发中的一个重要理念&#xff0c;倡导以最简单的方式实现软件功能&#xff0c;以确保代码清晰易懂、易维护&#xff0c;并在项目需求变化时能够快速适应。 其核心目标是避免复杂和过度设计&#xff0c;遵循“让事情保…...

HDFS分布式存储 zookeeper

hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架&#xff0c;允许使用简单的变成模型跨计算机对大型集群进行分布式处理&#xff08;1.海量的数据存储 2.海量数据的计算&#xff09;Hadoop核心组件 hdfs&#xff08;分布式文件存储系统&#xff09;&a…...

springboot整合VUE之在线教育管理系统简介

可以学习到的技能 学会常用技术栈的使用 独立开发项目 学会前端的开发流程 学会后端的开发流程 学会数据库的设计 学会前后端接口调用方式 学会多模块之间的关联 学会数据的处理 适用人群 在校学生&#xff0c;小白用户&#xff0c;想学习知识的 有点基础&#xff0c;想要通过项…...

人工智能(大型语言模型 LLMs)对不同学科的影响以及由此产生的新学习方式

今天是关于AI如何在教学中增强学生的学习体验&#xff0c;我把重要信息标红了。人文学科的价值被低估了 ⬇️ 转型与必要性 人工智能正在深刻地改变教育&#xff0c;这并非炒作&#xff0c;而是已经发生的巨大变革。教育机构和教育者不能忽视它&#xff0c;试图简单地禁止学生使…...