使用SpringBoot+InfluxDB實(shí)現(xiàn)高效數(shù)據(jù)存儲(chǔ)與查詢(xún)
1、項(xiàng)目介紹
本項(xiàng)目使用 Spring Boot + InfluxDB 2.x 來(lái)存儲(chǔ)和查詢(xún)時(shí)間序列數(shù)據(jù),適用于 物聯(lián)網(wǎng)(IoT)、實(shí)時(shí)監(jiān)控、日志分析 等場(chǎng)景。
2、 InfluxDB 介紹
InfluxDB 是一個(gè)高性能的時(shí)間序列數(shù)據(jù)庫(kù)(TSDB),適用于存儲(chǔ)溫度、傳感器數(shù)據(jù)、日志、監(jiān)控指標(biāo)等。
特點(diǎn):
- 采用 Flux 查詢(xún)語(yǔ)言
- 高吞吐量,支持 批量寫(xiě)入
- Tag(索引)+ Field(數(shù)據(jù)) 結(jié)構(gòu),提高查詢(xún)效率
- 精確時(shí)間戳(支持納秒級(jí))
3、Spring Boot 配置 InfluxDB
在 application.yml 中配置 InfluxDB 連接:
# InfluxDB 獨(dú)立配置 influxdb: url: http://192.168.1.1xx:28086/ # InfluxDB 服務(wù)器地址 token: _7FZlXGJJcd8Ayox-F-hVBDdXb_a5SI3530x1DdFKZfQ65uOhnpQciJWHpd7ULhpAOcgj5oV2JsR-Xf0qTtAxg== org: xxx # 組織名稱(chēng) bucket: xxx # 存儲(chǔ)桶名稱(chēng) # InfluxDB 客戶端日志級(jí)別 # ERROR: 僅記錄錯(cuò)誤日志 # WARN: 記錄警告和錯(cuò)誤日志 # INFO: 記錄普通信息、警告和錯(cuò)誤日志 # DEBUG: 記錄調(diào)試級(jí)別的詳細(xì)日志 # BODY: 記錄完整的 HTTP 請(qǐng)求和響應(yīng)主體 # TRACE: 記錄極其詳細(xì)的跟蹤日志 # ALL: 記錄所有日志級(jí)別(視客戶端而定) 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);
}
}說(shuō)明
InfluxDBClientFactory.create(url, token, org, bucket)創(chuàng)建 InfluxDB 客戶端@Value讀取application.yml配置
5、Service 層:數(shù)據(jù)寫(xiě)入 & 查詢(xún)
5.1 單條數(shù)據(jù)寫(xiě)入
public void writeSingleData(TemperatureDTO temperatureDTO) {
WriteApiBlocking writeApi = influxDBClient.getWriteApiBlocking();
Point point = Point.measurement("temperature")
.addTag("location", temperatureDTO.getLocation()) // 添加標(biāo)簽(索引)
.addField("value", temperatureDTO.getValue()) // 添加字段(數(shù)據(jù))
.time(Instant.now(), WritePrecision.NS); // 記錄當(dāng)前時(shí)間戳
writeApi.writePoint(point);
}5.2 批量寫(xiě)入(異步)
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("?? 寫(xiě)入失敗:" + error.getMessage());
} else {
writeApi.close(); // 關(guān)閉 API 避免資源泄露
log.info("? 批量數(shù)據(jù)寫(xiě)入成功(異步)");
}
});
}說(shuō)明
- 異步寫(xiě)入 不會(huì)阻塞主線程,提高吞吐量
- 異?;卣{(diào) 捕獲寫(xiě)入失敗的信息
- 使用
writeApi.close()避免資源泄露
5.3 查詢(xún)數(shù)據(jù)
public List<TemperatureVO> queryTemperatureData() {
String query = "from(bucket: \"test\") |> range(start: -1h)";
QueryApi queryApi = influxDBClient.getQueryApi();
return queryApi.query(query)
.stream()
.flatMap(fluxTable -> fluxTable.getRecords().stream()) // 遍歷 FluxTable
.map(record -> {
TemperatureVO vo = new TemperatureVO();
vo.setLocation((String) record.getValueByKey("location")); // 獲取標(biāo)簽信息
Object valueObj = record.getValueByKey("_value");
vo.setValue(valueObj != null ? ((Number) valueObj).doubleValue() : 0.0);
vo.setTimestamp(record.getTime().toString());
return vo;
})
.collect(Collectors.toList());
}說(shuō)明
- Flux 查詢(xún) 過(guò)去
1h內(nèi)的數(shù)據(jù) - 遍歷
FluxTable提取 標(biāo)簽 + 字段 數(shù)據(jù)
6、Controller 層:API 設(shè)計(jì)
@RestController
@RequestMapping("/api/influxdb")
public class InfluxDBController {
@Autowired
private TestService influxDBService;
@PostMapping("/write")
public String writeData(@RequestBody TemperatureDTO temperatureDTO) {
influxDBService.writeSingleData(temperatureDTO);
return "? 單條數(shù)據(jù)寫(xiě)入成功!";
}
@PostMapping("/write-batch")
public String writeBatchData() {
List<TemperatureDTO> data = generateTestData(10000);
influxDBService.writeBatchData(data);
return "? 10,000 條數(shù)據(jù)成功寫(xiě)入!";
}
@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;
}
}說(shuō)明
/write? 單條寫(xiě)入/write-batch? 生成 10,000 條數(shù)據(jù)并寫(xiě)入/query? 查詢(xún)過(guò)去 1 小時(shí)數(shù)據(jù)
7、運(yùn)行 & 測(cè)試
7.1 啟動(dòng)項(xiàng)目
mvn spring-boot:run
7.2 使用 Postman 進(jìn)行測(cè)試
1、寫(xiě)入單條數(shù)據(jù)
POST http://localhost:8080/api/influxdb/write
{
"location": "office-1",
"value": 22.5
}2、批量寫(xiě)入
POST http://localhost:8080/api/influxdb/write-batch
3、查詢(xún)數(shù)據(jù)
GET http://localhost:8080/api/influxdb/query
以上就是使用SpringBoot+InfluxDB實(shí)現(xiàn)高效數(shù)據(jù)存儲(chǔ)與查詢(xún)的詳細(xì)內(nèi)容,更多關(guān)于SpringBoot InfluxDB數(shù)據(jù)存儲(chǔ)與查詢(xún)的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
c語(yǔ)言來(lái)實(shí)現(xiàn)貪心算法之裝箱問(wèn)題
這篇文章主要介紹了c語(yǔ)言來(lái)實(shí)現(xiàn)貪心算法之裝箱問(wèn)題,需要的朋友可以參考下2015-03-03
springboot簡(jiǎn)單接入websocket的操作方法
這篇文章主要介紹了springboot簡(jiǎn)單接入websocket的方法,本文給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2021-05-05
spring MVC中傳遞對(duì)象參數(shù)示例詳解
這篇文章主要給大家介紹了在spring MVC中傳遞對(duì)象參數(shù)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起看吧。2017-06-06
IDEA中make directory as的作用及說(shuō)明
這篇文章主要介紹了IDEA中make directory as的作用及說(shuō)明,具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2024-09-09
mybatis之調(diào)用帶輸出參數(shù)的存儲(chǔ)過(guò)程(Oracle)
這篇文章主要介紹了mybatis調(diào)用帶輸出參數(shù)的存儲(chǔ)過(guò)程(Oracle),具有很好的參考價(jià)值,希望對(duì)大家有所幫助,如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-11-11
在Java中Collection的一些常用方法總結(jié)
今天給大家?guī)?lái)的知識(shí)是關(guān)于Java的,文章圍繞著Java中Collection的一些常用方法展開(kāi),文中有非常詳細(xì)的介紹及代碼示例,需要的朋友可以參考下2021-06-06

