阿里巴巴提供的控制台只是用于演示 Sentinel 的基本能力和工做流程,并无依赖生产环境中所必需的组件,好比持久化的后端数据库、可靠的配置中心等。目前 Sentinel 采用内存态的方式存储监控和规则数据,监控最长存储时间为 5 分钟,控制台重启后数据丢失。前端
这里推荐一下阿里云的官方版,AHAS Sentinel 控制台 是 Sentinel 控制台的阿里云上版本,提供企业级的控制台服务,包括:java
免费版,能够提供 5 个节点的免费额度。开通专业版便可享受不限量节点额度。python
专业版没有实例链接限制,开通后天天前5个限流降级节点不计费,超出部分按3元/天/实例收取相应的费用。git
官方文档也提供了思路,若须要监控数据持久化的功能,能够自行扩展实现 MetricsRepository 接口(0.2.0 版本),而后注册成 Spring Bean 并在相应位置经过 @Qualifier 注解指定对应的 bean name 便可。MetricsRepository 接口定义了如下功能:github
save 与 saveAll:存储对应的监控数据spring
queryByAppAndResourceBetween:查询某段时间内的某个应用的某个资源的监控数据docker
listResourcesOfApp:查询某个应用下的全部资源数据库
其中默认的监控数据类型为 MetricEntity,包含应用名称、时间戳、资源名称、异常数、请求经过数、请求拒绝数、平均响应时间等信息。后端
对于监控数据的存储,用户须要根据本身的存储精度,来考虑如何存储这些监控数据。显然咱们要使用目前最流行的时序数据库InfluxDB
解决方案,不要问什么?闭眼享受就能够了。并发
InfluxDB
是一个开源分布式时序、事件和指标数据库。使用 Go 语言编写,无需外部依赖。
应用:性能监控,应用程序指标,物联网传感器数据和实时分析等的后端存储。
强大的类SQL语法
内置http支持,使用http读写
基于事件:它支持任意的事件数据
无结构(无模式):能够是任意数量的列
可度量性:你能够实时对大量数据进行计算
持续高并发写入、无更新、数据压缩存储、低查询延时
支持min, max, sum, count, mean, median 等一系列函数
基于时间序列,支持与时间有关的相关函数(如最大,最小,求和等)
首先你得先有个 Influxdb 数据库,建议使用 Docker 方式安装,更多能够参考文末连接。
须要注意的是,从1.1.0版开始不推荐使用管理员界面,并将在1.3.0版中删除。默认状况下禁用。若是须要,仍能够经过设置以下环境变量来启用它。
如下端口很重要,并由InfluxDB
使用。
chronograf
经过该命令, 生成默认配置文件:
docker run --rm influxdb influxd config > influxdb.conf
建立并运行容器:
docker run -d \ -p 8086:8086 \ -p 8083:8083 \ -e INFLUXDB_ADMIN_ENABLED=true \ -v $PWD/data:/var/lib/influxdb/ \ -v $PWD/config/influxdb.conf:/etc/influxdb/influxdb.conf:ro \ --name influx \ influxdb -config /etc/influxdb/influxdb.conf
生产环境必定要开启权限验证,修改 influxdb.conf 配置:
[http] enabled = true bind-address = ":8086" auth-enabled = true # 鉴权
建立用户:
# 进入容器 docker exec -it influx /bin/sh # 链接 influx # 建立用户 CREATE USER admin with PASSWORD 'admin' WITH ALL PRIVILEGES
退出从新登陆:
# 用户密码登陆 influx -username admin -password admin # 建立数据库 CREATE DATABASE sentinel_log
pom.xml引入 influxdb 官方开源工具包:
<dependency> <groupId>org.influxdb</groupId> <artifactId>influxdb-java</artifactId> <version>2.15</version> </dependency>
配置文件引入:
# 自行替换 API 地址:端口 spring.influx.url=http://127.0.0.1:8086 spring.influx.user=admin spring.influx.password=admin spring.influx.database=sentinel_log
配置数据源:
/** * InfluxDb 配置 * 建立者 爪哇笔记 * 网址 https://blog.52itstyle.vip */ @Configuration public class InfluxDbConfig { @Value("${spring.influx.url:''}") private String influxDBUrl; @Value("${spring.influx.user:''}") private String userName; @Value("${spring.influx.password:''}") private String password; @Value("${spring.influx.database:''}") private String database; @Bean public InfluxDB influxDB(){ InfluxDB influxDB = InfluxDBFactory.connect(influxDBUrl, userName, password); try { /** * 异步插入: * enableBatch这里第一个是point的个数,第二个是时间,单位毫秒 * point的个数和时间是联合使用的,若是满100条或者2000毫秒 * 知足任何一个条件就会发送一次写的请求。 */ influxDB.setDatabase(database) .enableBatch(100,2000, TimeUnit.MILLISECONDS); } catch (Exception e) { e.printStackTrace(); } finally { influxDB.setRetentionPolicy("autogen"); } influxDB.setLogLevel(InfluxDB.LogLevel.BASIC); return influxDB; } }
实现 MetricsRepository 接口,重写实现:
/** * 数据CURD * 建立者 爪哇笔记 * 网址 https://blog.52itstyle.vip */ @Component("inInfluxdbMetricsRepository") public class InInfluxdbMetricsRepository implements MetricsRepository<MetricEntity> { @Autowired public InfluxDB influxDB; @Override public synchronized void save(MetricEntity metric) { //省略代码,太长了,参考内存写法,参考 saveAll 这里是单条插入 } @Override public synchronized void saveAll(Iterable<MetricEntity> metrics) { if (metrics == null) { return; } BatchPoints batchPoints = BatchPoints.builder() .tag("async", "true") .consistency(InfluxDB.ConsistencyLevel.ALL) .build(); metrics.forEach(metric->{ Point point = Point .measurement("sentinelInfo") //这里使用微妙、若是还有覆盖数据就使用纳秒,保证 time 和 tag 惟一就能够 .time(System.currentTimeMillis(), TimeUnit.MICROSECONDS) .tag("app",metric.getApp())//tag 数据走索引 .addField("gmtCreate", metric.getGmtCreate().getTime()) .addField("gmtModified", metric.getGmtModified().getTime()) .addField("timestamp", metric.getTimestamp().getTime()) .addField("resource", metric.getResource()) .addField("passQps", metric.getPassQps()) .addField("successQps", metric.getSuccessQps()) .addField("blockQps", metric.getBlockQps()) .addField("exceptionQps", metric.getExceptionQps()) .addField("rt", metric.getRt()) .addField("count", metric.getCount()) .addField("resourceCode", metric.getResourceCode()) .build(); batchPoints.point(point); }); //批量插入 influxDB.write(batchPoints); } @Override public synchronized List<MetricEntity> queryByAppAndResourceBetween(String app, String resource, long startTime, long endTime) { //省略代码,太长了,参考内存写法 } @Override public synchronized List<String> listResourcesOfApp(String app) { //省略代码,太长了,参考内存写法 } }
分别修改 MetricFetcher
和 MetricController
中 metricStore
的注入方式,使用 Influxdb
实现:
/** * 注入 * 建立者 爪哇笔记 * 网址 https://blog.52itstyle.vip */ @Autowired @Qualifier("inInfluxdbMetricsRepository") private MetricsRepository<MetricEntity> metricStore;
配置完成后,咱们重启控制台,而后访问客户端项目,若是控制台打印如下数据,说明配置成功:
2019-09-21 19:47:25 [sentinel-dashboard-metrics-fetchWorker-thread-2] INFO okhttp3.OkHttpClient - --> POST http://118.190.247.102:8086/write?db=sentinel_log&precision=n&consistency=all (486-byte body) 2019-09-21 19:47:25 [sentinel-dashboard-metrics-fetchWorker-thread-2] INFO okhttp3.OkHttpClient - <-- 204 No Content http://118.190.247.102:8086/write?db=sentinel_log&precision=n&consistency=all (46ms, 0-byte body)
多访问几回客户端项目,而后登录控制台查看,出现如下效果,说明改形成功:
注意事项:
官方前端并无实现按照时间范围的查询搜索,须要自行实现
官方控制台实时监控默认查询的是最近一分钟的热点资源排行,见方法 listResourcesOfApp
官方控制台实时监控右侧 Table 默认查询的是最近五分钟的热点访问详情,见方法 queryTopResourceMetric
对于官方五分钟的阉割版,时序数据库实现的流控数据存储,对于生产环境仍是颇有帮助的,好比实时数据分析,热点资源、监控预警等等。小伙伴们还能够根据实际生产需求结合Chronograf
、Grafana
作出更炫酷的大屏监控。
https://gitee.com/52itstyle/sentinel-dashboard
https://blog.52itstyle.vip/archives/4460/
https://hub.docker.com/_/influxdb
https://hub.docker.com/_/chronograf
https://github.com/influxdata/influxdb-java
https://github.com/influxdata/influxdb-python
https://help.aliyun.com/document_detail/97578.htm