前言
阿里巴巴提供的控制台只是用于演示 Sentinel 的基本能力和工作流程, 并没有依赖生产环境中所必需的组件, 比如持久化的后端数据库, 可靠的配置中心等. 目前 Sentinel 采用内存态的方式存储监控和规则数据, 监控最长存储时间为 5 分钟, 控制台重启后数据丢失.
企业版
这里推荐一下阿里云的官方版, AHAS Sentinel 控制台 是 Sentinel 控制台的阿里云上版本, 提供企业级的控制台服务, 包括:
实时请求链路查看
还有各种酷炫的监控图表
可靠的实时监控和历史监控数据查询, 无需自行存储, 拉取
动态规则管理 / 推送, 无需自行配置外部数据源
免费版, 可以提供 5 个节点的免费额度. 开通专业版即可享受不限量节点额度.
专业版没有实例连接限制, 开通后每天前 5 个限流降级节点不计费, 超出部分按 3 元 / 天 / 实例收取相应的费用.
思路
官方文档也提供了思路, 若需要监控数据持久化的功能, 可以自行扩展实现 MetricsRepository 接口 (0.2.0 版本), 然后注册成 Spring Bean 并在相应位置通过 @Qualifier 注解指定对应的 bean name 即可. MetricsRepository 接口定义了以下功能:
save 与 saveAll: 存储对应的监控数据
queryByAppAndResourceBetween: 查询某段时间内的某个应用的某个资源的监控数据
listResourcesOfApp: 查询某个应用下的所有资源
其中默认的监控数据类型为 MetricEntity, 包含应用名称, 时间戳, 资源名称, 异常数, 请求通过数, 请求拒绝数, 平均响应时间等信息.
对于监控数据的存储, 用户需要根据自己的存储精度, 来考虑如何存储这些监控数据. 显然我们要使用目前最流行的时序数据库 InfluxDB 解决方案, 不要问什么? 闭眼享受就可以了.
选型
InfluxDB 是一个开源分布式时序, 事件和指标数据库. 使用 Go 语言编写, 无需外部依赖.
应用: 性能监控, 应用程序指标, 物联网传感器数据和实时分析等的后端存储.
强大的类 SQL 语法
内置 http 支持, 使用 http 读写
基于事件: 它支持任意的事件数据
无结构 (无模式): 可以是任意数量的列
可度量性: 你可以实时对大量数据进行计算
持续高并发写入, 无更新, 数据压缩存储, 低查询延时
支持 min, max, sum, count, mean, median 等一系列函数
基于时间序列, 支持与时间有关的相关函数 (如最大, 最小, 求和等)
改造
InfluxDB 安装
首先你得先有个 Influxdb 数据库, 建议使用 Docker 方式安装, 更多可以参考文末链接.
需要注意的是, 从 1.1.0 版开始不推荐使用管理员界面, 并将在 1.3.0 版中删除. 默认情况下禁用. 如果需要, 仍可以通过设置如下环境变量来启用它.
以下端口很重要, 并由 InfluxDB 使用.
8086 HTTP API 端口
8083 管理员界面端口 (如果已启用, 1.7.8 貌似启用也不好使), 官方推荐使用 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
Sentinel 控制台改造
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
来源: https://www.cnblogs.com/smallSevens/p/11576263.html