zoukankan      html  css  js  c++  java
  • SpringBoot 2.0 + InfluxDB+ Sentinel 实时监控数据存储

    前言

    阿里巴巴提供的控制台只是用于演示 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) {
    	   //省略代码,太长了,参考内存写法
        }
    }
    

    分别修改 MetricFetcherMetricControllermetricStore 的注入方式,使用 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

    小结

    对于官方五分钟的阉割版,时序数据库实现的流控数据存储,对于生产环境还是很有帮助的,比如实时数据分析,热点资源、监控预警等等。小伙伴们还可以根据实际生产需求结合ChronografGrafana 做出更炫酷的大屏监控。

    源码

    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

  • 相关阅读:
    navigateTo防止多次跳转
    vue中的绑定class和微信小程序中的绑定class的区别
    js同步和异步
    本地存储和vuex使用对比
    微信小程序页面跳转区别总结
    CAS-技术专区-认证服务器cas-server搭建
    CAS-技术专区-SSO配置完整案例(静态认证+数据库认证)
    SpringCloud-技术专区-实战案例-Zuul整合OAuth2.0认证服务
    OAuth2.0协议专区-SpringCloud安全-集成OAuth2实现身份认证和单点登录
    OAuth2.0协议专区-SpringCloud微服务实战-基于OAUTH2.0统一认证授权的微服务基础架构
  • 原文地址:https://www.cnblogs.com/smallSevens/p/11576263.html
Copyright © 2011-2022 走看看