前言
在前面的系列博文里我们已经介绍过了sentinel的dashboard的基础用法,使用dashboard可以详细的监控被保护资源的实际访问统计情况,与为不同服务配置的限流规则。sentinel dashboard的功能显然不止于此,官方留了很多功能的入口供使用者自行扩展,本篇博客抛砖引玉。对dashboard流控数据统计持久化与dashboard动态配置限流规则两方面进行扩展。其它功能入口都可以采用同样的思路进行扩展
限流统计数据持久化
sentinel默认收集到的统计数据是保存在内存中的,且有效时间只有五分钟,即使出了故障我们也无法追查五分钟之前的数据,而当接入sentinel的应用过多的情况下,内存消耗也很巨大(这一点为了实时的在dashboard查看流量趋势可以妥协),所以我们需要将统计的数据持久化下来。
sentinel本质是一个web应用程序,所以他一定有自己的dao层,我们打开浏览器查看获取浏览统计的接口
/metric/queryTopResourceMetric.json
定位到sentinel dashboard的源码,接口位于MetricController类中,这个类里注入了一个dao层的bean
@Autowired
private MetricsRepository<MetricEntity> metricStore;
操作的实体叫MetricEntity,看来这就是我们要找的东西了,它有以下属性,都是与流控统计相关的
com.alibaba.csp.sentinel.dashboard.datasource.entity.MetricEntity
public class MetricEntity {
private Long id;
private Date gmtCreate;
private Date gmtModified;
private String app;
/**
* 监控信息的时间戳
*/
private Date timestamp;
private String resource;
private Long passQps;
private Long successQps;
private Long blockQps;
private Long exceptionQps;
/**
* summary rt of all success exit qps.
*/
private double rt;
/**
* 本次聚合的总条数
*/
private int count;
private int resourceCode;
...
}
MetricRepository是一个接口。我们只需要实现它然后替换controller中它的注入即可达到dao层替换的效果,它有以下三个方法
com.alibaba.csp.sentinel.dashboard.repository.metric.MetricsRepository
public interface MetricsRepository<T> {
/**
* Save the metric to the storage repository.
*
* @param metric metric data to save
*/
void save(T metric);
/**
* Save all metrics to the storage repository.
*
* @param metrics metrics to save
*/
void saveAll(Iterable<T> metrics);
/**
* Get all metrics by {@code appName} and {@code resourceName} between a period of time.
*
* @param app application name for Sentinel
* @param resource resource name
* @param startTime start timestamp
* @param endTime end timestamp
* @return all metrics in query conditions
*/
List<T> queryByAppAndResourceBetween(String app, String resource, long startTime, long endTime);
/**
* List resource name of provided application name.
*
* @param app application name
* @return list of resources
*/
List<String> listResourcesOfApp(String app);
}
MetricsRepository的具体实现就不贴了,选顺手的orm框架实现增删改查即可,需要注意的是这时候容器里MetricsRepository的实现类就不止一个了,继续使用@Autowired注入会出问题,需要使用@Qualifier指定我们自己的实现或者排除对旧的bean的注入。
建表sql参照MetricEntity的属性编写即可,保证MetricEntity的每个属性都被完整记录下来
CREATE TABLE `sentinel_metric` (
`id` int(10) NOT NULL AUTO_INCREMENT,
`gmt_create` bigint(20) DEFAULT NULL,
`gmt_modified` bigint(20) DEFAULT NULL,
`app` varchar(100) DEFAULT NULL,
`timestamp` bigint(20) DEFAULT NULL,
`resource` varchar(100) DEFAULT NULL,
`pass_qps` bigint(20) DEFAULT NULL,
`success_qps` bigint(20) DEFAULT NULL,
`block_qps` bigint(20) DEFAULT NULL,
`exception_qps` bigint(20) DEFAULT NULL,
`rt` double(10,0) DEFAULT NULL,
`count` bigint(20) DEFAULT NULL,
`resource_code` bigint(20) DEFAULT NULL,
PRIMARY KEY (`id`),
KEY `app_idx` (`app`) USING BTREE,
KEY `resource_idx` (`resource<