Sentinel console real-time monitoring data persistence [Mysql]

According to Sentinel's official documentation, the monitoring data in the Sentinel console is directly stored in memory after aggregation, and is not persisted, and only the monitoring data of the last 5 minutes is retained. If you need to monitor the data persistence function, you need to extend and implement the MetricsRepository interface yourself.

https://github.com/alibaba/Sentinel/wiki/Using the Sentinel-Console in the Production Environment The documentation also gives guidance steps:
1. Extend and implement the MetricsRepository interface by yourself;
2. Register as a Spring Bean and register it in the corresponding The location can specify the corresponding bean name through the @Qualifier annotation.

Add Maven dependency

Add the following to the pom.xml of sentinel-dashboard:

<!-- 添加mybatisplus依赖 -->
<dependency>
    <groupId>com.baomidou</groupId>
    <artifactId>mybatis-plus-boot-starter</artifactId>
    <version>3.0.5</version>
</dependency>

<!-- 添加mysql依赖,版本自定义 -->
<dependency>
    <groupId>mysql</groupId>
    <artifactId>mysql-connector-java</artifactId>
    <version>8.0.28</version>
</dependency>

Here I use the mybatis enhancement tool mybatisplus to operate the database. Since sentinel is developed based on the springboot 2.0.5.RELEASE version, the version selected by mybatisplus is 3.0.5.

There will be problems with integrating a higher version of mybatisplus. mybatisplus 3.0.6 uses springboot 2.1.0.RELEASE

database script

CREATE TABLE `sentinel_metrics` (
  `id` bigint(20) unsigned NOT NULL AUTO_INCREMENT COMMENT '主键ID',
  `gmt_create` datetime DEFAULT NULL COMMENT '创建时间',
  `gmt_modified` datetime DEFAULT NULL COMMENT '修改时间',
  `app` varchar(100) DEFAULT NULL COMMENT '应用名称',
  `timestamp` datetime DEFAULT NULL COMMENT '监控信息的时间戳',
  `resource` varchar(500) DEFAULT NULL COMMENT '资源名',
  `pass_qps` bigint(20) DEFAULT NULL COMMENT '通过QPS',
  `success_qps` bigint(20) DEFAULT NULL COMMENT '成功QPS',
  `block_qps` bigint(20) DEFAULT NULL COMMENT '拒绝QPS',
  `exception_qps` bigint(20) DEFAULT NULL COMMENT '异常QPS',
  `rt` double DEFAULT NULL COMMENT '所有successQps的rt的和',
  `count` int(11) DEFAULT NULL COMMENT '本次聚合的总条数',
  `resource_code` int(11) DEFAULT NULL COMMENT '资源的hashCode',
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4;

Modify application.properties configuration

Add the following configuration at the end of the application.properties configuration file:

spring.datasource.driver-class-name=com.mysql.cj.jdbc.Driver
spring.datasource.url=jdbc:mysql://127.0.0.1:3306/sentinel?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8&allowMultiQueries=true
spring.datasource.username=****
spring.datasource.password=****

mybatis-plus.global-config.db-config.id-type=auto
mybatis-plus.global-config.db-config.field-strategy=not_null
mybatis-plus.global-config.db-config.table-underline=true
mybatis-plus.global-config.db-config.db-type=mysql

mybatis-plus.mapper-locations=xml/*Mapper.xml # mybatis mapper文件地址
mybatis-plus.type-aliases-package=com.alibaba.csp.sentinel.dashboard.datasource.entity # 实体类路径
mybatis-plus.configuration.log-impl=org.apache.ibatis.logging.stdout.StdOutImpl

database entity class

/**
 * <p>
 *
 * </p>
 *
 * @author tigerkin
 * @since 2022-03-08
 */
@TableName("sentinel_metrics")
public class SentinelMetricsEntity extends Model<SentinelMetricsEntity> {

    private static final long serialVersionUID = 1L;

    /**
     * 主键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;

	/** getter、setter、toString方法 **/
}

Implement the MetricsRepository interface

  • save and saveAll: store the corresponding monitoring data
  • queryByAppAndResourceBetween: Query the monitoring data of a resource of an application within a certain period of time
  • listResourcesOfApp: Query all resources under an application
/**
 * @ClassName CutsomMetricsRepository
 * @Description
 * @Author tigerkin
 * @Date 2022/3/8 15:40
 */
@Component
@MapperScan(value = {"com.alibaba.csp.sentinel.dashboard.mapper"})
public class CustomMetricsRepository implements MetricsRepository<MetricEntity>{

    private static final Logger LOG = LoggerFactory.getLogger(CustomMetricsRepository.class);

    @Autowired
    SentinelMetricsMapper sentinelMetricsMapper;

    private final ReentrantReadWriteLock readWriteLock = new ReentrantReadWriteLock();

    @Override
    public void save(MetricEntity entity) {
        if (entity == null || StringUtil.isBlank(entity.getApp())) {
            return;
        }
        readWriteLock.writeLock().lock();
        try {
            LOG.info("========> save -> entity: {}", entity.toString());
            SentinelMetricsEntity metrics = SentinelMetricsEntity.setSentinelMetrics(entity);
            metrics.insert();
        } finally {
            readWriteLock.writeLock().unlock();
        }
    }

    @Override
    public void saveAll(Iterable<MetricEntity> metrics) {
        if (metrics == null) {
            return;
        }
        readWriteLock.writeLock().lock();
        try {
            LOG.info("========> saveAll -> metrics: {}", metrics.toString());
            List<SentinelMetricsEntity> metricsIns = new ArrayList<>();
            metrics.forEach(e -> metricsIns.add(SentinelMetricsEntity.setSentinelMetrics(e)));
            sentinelMetricsMapper.insertBatch(metricsIns);
        } finally {
            readWriteLock.writeLock().unlock();
        }
    }

    @Override
    public 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 {
            QueryWrapper<SentinelMetricsEntity> qw = new QueryWrapper<>();
            qw.eq("app", app);
            qw.eq("resource", resource);
            qw.ge("timestamp", new Date(startTime));
            qw.le("timestamp", new Date(endTime));
            qw.orderByAsc("timestamp");
            List<SentinelMetricsEntity> sentinelMetrics = sentinelMetricsMapper.selectList(qw);
            return sentinelMetrics.stream().map(e -> SentinelMetricsEntity.setMetricEntity(e)).collect(Collectors.toList());
        } finally {
            readWriteLock.readLock().unlock();
        }
    }

    @Override
    public List<String> listResourcesOfApp(String app) {
        List<String> results = new ArrayList<>();
        if (StringUtil.isBlank(app)) {
            return results;
        }

        readWriteLock.readLock().lock();
        try {
            results = sentinelMetricsMapper.selectResourceByApp(app);
            return results;
        } finally {
            readWriteLock.readLock().unlock();
        }
    }
}

Specify the type of MetricsRepository dependency injection

Add @Qualifier("customMetricsRepository") to the MetricsRepository properties in the MetricController and MetricFetcher classes

MetricController:
insert image description here
MetricFetcher:
insert image description here

You can modify the statistics time in MetricController, the default is 5 minutes, here I changed it to 30 minutes.
insert image description here

Finally start the sentinel-dashboard project.
insert image description here
insert image description here
At this point, the Sentinel real-time monitoring data persistence is realized, and the monitoring data can also be seen by restarting the Sentinel console.

mybatisplus official documentation: https://baomidou.com/pages/24112f/
sentinel source code: https://github.com/alibaba/Sentinel
sentinel official documentation:
https://github.com/alibaba/Sentinel/wiki/console
https://github.com/alibaba/Sentinel/wiki/Using-Sentinel-Console in Production

Guess you like

Origin blog.csdn.net/weixin_42270645/article/details/123416086