使用SpringBoot+InfluxDB实现高效数据存储与查询

本文主要是介绍使用SpringBoot+InfluxDB实现高效数据存储与查询,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

《使用SpringBoot+InfluxDB实现高效数据存储与查询》InfluxDB是一个开源的时间序列数据库,特别适合处理带有时间戳的监控数据、指标数据等,下面详细介绍如何在SpringBoot项目...

1、项目介绍

本项目使用 Spring Boot + InfluxDB 2.x 来存储和查询时间序列数据,适用于 物联网(IoT)、实时监控、日志分析 等场景。

2、 InfluxDB 介绍

InfluxDB 是一个高性能的时间序列数据库(TSDB),适用于存储温度、传感器数据、日志、监控指标等。

特点

  • 采用 Flux 查询语言
  • 高吞吐量,支持 批量写入
  • Tag(索引)+ Field(数据) 结构,提高查询效率
  • 精确时间戳(支持纳秒级)

3、Spring Boot 配置 InfluxDB

application.yml 中配置 InfluxDB 连接:

# China编程InfluxDB 独立配置
influxdb:
  url: http://192.168.1.1xx:28086/  # InfluxDB 服务器地址
  token: _7FZlXGJJcd8Ayox-F-hvbDdXb_a5SI3530x1DdFKZfQ65uOhnpQciJWHpd7ULhpAOcgj5oV2jsR-Xf0qTtAxg==
  org: xxx     # 组织名称
  bucket: xxx  # 存储桶名称
  # InfluxDB 客户端日志级别
  # ERROR: 仅js记录错误日志
  # WARN: 记录警告和错误日志
  # INFO: 记录普通信息、警告和错误日志
  # DEBUG: 记录调试级别的详细日志
  # BODY: 记录完整的 HTTP 请求和响应主体
  # TRACE: 记录极其详细的跟踪日志
  # ALL: 记录所有日志级别(视客户端而定)
  logLevel: BODY

4、InfluxDB 连接配置

InfluxDBConfig.Java 中配置 InfluxDB 客户端:

import com.influxdb.client.InfluxDBClient;
import com.influxdb.client.InfluxDBClientFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
 
@Configuration
public class InfluxDBConfig {
 
    @Value("${influxdb.url}")
    private String url;
 
    @Value("${influxdb.token}")
    private String token;
 
    @Value("${influxdb.org}")
    private String org;
 
    @Value("${influxdb.bucket}")
    private String bucket;
 
    @Bean
    public InfluxDBClient influxDBClient() {
        return InfluxDBClientFactory.create(url, token.toCharArray(), org, bucket);
    }
}

说明

  • InfluxDBClientFactory.create(url, token, org, bucket) 创建 InfluxDB 客户端
  • @Value 读取 application.yml 配置

5、Service 层:数据写入 & 查询

5.1 单条数据写入

public void writeSingleData(TemperatureDTO temperatureDTO) {
    WriteApiblocking writeApi = influxDBClient.getWriteApiBlocking();
    
    Point point = Point.measurement("temperature")
            .addTag("location", temperatureDTO.getLocation()) // 添加标签(索引)
            .addField("value", temperatureDTO.getValue()) // 添加字段(数据)
            .time(Instant.now(), WritePrecision.NS); // 记录当前时间戳
 
    writeApi.writePoint(point);
}

5.2 批量写入(异步)

public void writeBATchData(List<TemperatureDTO> temperatureDTOs) {
    WriteApi writeApi = influxDBClient.makeWriteApi(); // 获取异步 API
 
    List<Point> points = temperatureDTOs.stream()
            .map(dto -> Point.measurement("temperature")
                    .addTag("location", dto.getLocation())
                    .addField("value", dto.getValue())
                    .time(Instant.now(), WritePrecision.NS))
            .collect(Collectors.toList());
 
    CompletableFuture<Void> future = CompletableFuture.runAsync(() -> writeApi.writePoints(points));
    future.whenComplete((result, error) -> {
        if (error != null) {
            System.err.println(" 写入失败:" + error.getMessage());
        } else {
            writeApi.close();  // 关闭 API 避免资源泄露
            log.info("✅ 批量数据写入成功(异步)");
        }
    });
}

说明

  • 异步写入 不会阻塞主线程,提高吞吐量
  • 异常回调 捕获写入失败的信息
  • 使用 writeApi.close() 避免资源泄露

5.3 查询数据

public List<TemperatureVO> queryTemperatureData() {
    String query = "from(bucket: \"test\") |> range(start: -1h)";
    QueryApi queryApi = influxDBClient.getQueryApi();
 
    return queryApi.query(query)
            .stream()
            .flatMjuFXaap(fluxTable -> fluxTable.getRecords().stream()) // 遍历 FluxTable
            .map(record -> {
                TemperatureVO vo = new TempythonperatureVO();
                vo.setLocation((String) record.getValueByKey("location")); // 获取标签信息
                Object valueObj = record.getValueByKey("_value");
                vo.setValue(valueObj != null ? ((Number) valueObj).doubleValue() : 0.0);
                vo.setTimestamp(record.getTime().toString());
                return vo;
            })
            .collect(Collectors.toList());
}

说明

  • Flux 查询 过去 1h 内的数据
  • 遍历 FluxTable 提取 标签 + 字段 数据

6、Controller 层:API 设计

@RestController
@RequestMapping("/api/influxdb")
public class InfluxDBController {
 
   编程 @Autowired
    private TestService influxDBService;
 
    @PostMapping("/write")
    public String writeData(@RequestBody TemperatureDTO temperatureDTO) {
        influxDBService.writeSingleData(temperatureDTO);
        return "✅ 单条数据写入成功!";
    }
 
    @PostMapping("/write-batch")
    public String writeBatchData() {
        List<TemperatureDTO> data = generateTestData(10000);
        influxDBService.writeBatchData(data);
        return "✅ 10,000 条数据成功写入!";
    }
 
    @GetMapping("/query")
    public List<TemperatureVO> queryTemperatureData() {
        return influxDBService.queryTemperatureData();
    }
 
    private List<TemperatureDTO> generateTestData(int count) {
        List<TemperatureDTO> dataList = new ArrayList<>();
        Random random = new Random();
        for (int i = 0; i < count; i++) {
            TemperatureDTO dto = new TemperatureDTO();
            dto.setLocation("office-" + (random.nextInt(1000) + 1));
            dto.setValue(15 + (random.nextDouble() * 10));
            dataList.add(dto);
        }
        return dataList;
    }
}

说明

  • /write单条写入
  • /write-batch生成 10,000 条数据并写入
  • /query查询过去 1 小时数据

7、运行 & 测试

7.1 启动项目

mvn spring-boot:run 

7.2 使用 Postman 进行测试

1、写入单条数据

POST http://localhost:8080/api/influxdb/write

{
  "location": "office-1",
  "value": 22.5
}

2、批量写入

POST http://localhost:8080/api/influxdb/write-batch

3、查询数据

GET http://localhost:8080/api/influxdb/query

以上就是使用SpringBoot+InfluxDB实现高效数据存储与查询的详细内容,更多关于SpringBoot InfluxDB数据存储与查询的资料请关注编程China编程(www.chinasem.cn)其它相关文章!

这篇关于使用SpringBoot+InfluxDB实现高效数据存储与查询的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1155781

相关文章

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

C++中unordered_set哈希集合的实现

《C++中unordered_set哈希集合的实现》std::unordered_set是C++标准库中的无序关联容器,基于哈希表实现,具有元素唯一性和无序性特点,本文就来详细的介绍一下unorder... 目录一、概述二、头文件与命名空间三、常用方法与示例1. 构造与析构2. 迭代器与遍历3. 容量相关4

Linux join命令的使用及说明

《Linuxjoin命令的使用及说明》`join`命令用于在Linux中按字段将两个文件进行连接,类似于SQL的JOIN,它需要两个文件按用于匹配的字段排序,并且第一个文件的换行符必须是LF,`jo... 目录一. 基本语法二. 数据准备三. 指定文件的连接key四.-a输出指定文件的所有行五.-o指定输出

Java中Redisson 的原理深度解析

《Java中Redisson的原理深度解析》Redisson是一个高性能的Redis客户端,它通过将Redis数据结构映射为Java对象和分布式对象,实现了在Java应用中方便地使用Redis,本文... 目录前言一、核心设计理念二、核心架构与通信层1. 基于 Netty 的异步非阻塞通信2. 编解码器三、

Linux jq命令的使用解读

《Linuxjq命令的使用解读》jq是一个强大的命令行工具,用于处理JSON数据,它可以用来查看、过滤、修改、格式化JSON数据,通过使用各种选项和过滤器,可以实现复杂的JSON处理任务... 目录一. 简介二. 选项2.1.2.2-c2.3-r2.4-R三. 字段提取3.1 普通字段3.2 数组字段四.

C++中悬垂引用(Dangling Reference) 的实现

《C++中悬垂引用(DanglingReference)的实现》C++中的悬垂引用指引用绑定的对象被销毁后引用仍存在的情况,会导致访问无效内存,下面就来详细的介绍一下产生的原因以及如何避免,感兴趣... 目录悬垂引用的产生原因1. 引用绑定到局部变量,变量超出作用域后销毁2. 引用绑定到动态分配的对象,对象

Linux kill正在执行的后台任务 kill进程组使用详解

《Linuxkill正在执行的后台任务kill进程组使用详解》文章介绍了两个脚本的功能和区别,以及执行这些脚本时遇到的进程管理问题,通过查看进程树、使用`kill`命令和`lsof`命令,分析了子... 目录零. 用到的命令一. 待执行的脚本二. 执行含子进程的脚本,并kill2.1 进程查看2.2 遇到的

SpringBoot基于注解实现数据库字段回填的完整方案

《SpringBoot基于注解实现数据库字段回填的完整方案》这篇文章主要为大家详细介绍了SpringBoot如何基于注解实现数据库字段回填的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解... 目录数据库表pom.XMLRelationFieldRelationFieldMapping基础的一些代

一篇文章彻底搞懂macOS如何决定java环境

《一篇文章彻底搞懂macOS如何决定java环境》MacOS作为一个功能强大的操作系统,为开发者提供了丰富的开发工具和框架,下面:本文主要介绍macOS如何决定java环境的相关资料,文中通过代码... 目录方法一:使用 which命令方法二:使用 Java_home工具(Apple 官方推荐)那问题来了,

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node