InfluxData【付诸实践 02】SpringBoot 集成时序数据库 InfluxDB 应用分享(InfluxDB实例+Feign接口调用InfluxDB API)源码分享

简介: InfluxData【付诸实践 02】SpringBoot 集成时序数据库 InfluxDB 应用分享(InfluxDB实例+Feign接口调用InfluxDB API)源码分享

1.InfluxDB实例

1.1 依赖及配置

<dependency>
  <groupId>org.influxdb</groupId>
  <artifactId>influxdb-java</artifactId>
  <version>2.15</version>
</dependency>
<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <optional>true</optional>
</dependency>
<dependency>
  <groupId>org.springframework.boot</groupId>
  <artifactId>spring-boot-starter-test</artifactId>
  <scope>test</scope>
</dependency>
spring:
  influx:
    url: http://tcloud:18088
    user: admin
    password: admin
    database: mydb
    retentionPolicy: default
    retentionPolicyTime: 30d

1.2 代码实现

配置类:

@Configuration
public class InfluxDatabaseConfig {
    @Value("${spring.influx.url}")
    public String url;
    @Value("${spring.influx.user}")
    public String userName;
    @Value("${spring.influx.password}")
    public String password;
    @Value("${spring.influx.database}")
    public String database;
    @Value("${spring.influx.retentionPolicy}")
    public String retentionPolicy;
    @Value("${spring.influx.retentionPolicyTime}")
    public String retentionPolicyTime;
}

工具类:

@Slf4j
@Component
public class InfluxDatabaseUtil {
    private String database;
    private String retentionPolicy;
    private String retentionPolicyTime;
    private InfluxDB influxdb;
    @Autowired
    private InfluxDatabaseConfig influxDatabaseConfig;
    @PostConstruct
    private void init() {
        // 保存策略
        if (StringUtils.isEmpty(influxDatabaseConfig.retentionPolicy)) {
            this.retentionPolicy = "autogen";
        } else {
            this.retentionPolicy = influxDatabaseConfig.retentionPolicy;
        }
        // 数据保存策略中数据保存时间
        if (StringUtils.isEmpty(influxDatabaseConfig.retentionPolicyTime)) {
            this.retentionPolicyTime = "30d";
        } else {
            this.retentionPolicyTime = influxDatabaseConfig.retentionPolicyTime;
        }
        if (StringUtils.isEmpty(influxDatabaseConfig.database)) {
            // 创建数据库并赋值
            System.out.println("创建数据库!");
        }
        this.database = influxDatabaseConfig.database;
        // 初始化 InfluxDB 实例
        initInfluxDatabase();
        // 数据库设置保存策略
        createRetentionPolicy();
    }
    /**
     * 初始化数据库连接
     */
    private void initInfluxDatabase() {
        influxdb = InfluxDBFactory.connect(influxDatabaseConfig.url, influxDatabaseConfig.userName, influxDatabaseConfig.password);
        influxdb.setDatabase(database);
    }
    /**
     * 设置数据保存策略
     * default 策略名
     * database 数据库名
     * 30d 数据保存时限30天
     * 1 副本个数为1
     * 结尾 DEFAULT 表示 设为默认的策略
     */
    private void createRetentionPolicy() {
        String command = String.format("CREATE RETENTION POLICY \"%s\" ON \"%s\" DURATION %s REPLICATION %s DEFAULT",
                retentionPolicy, database, retentionPolicyTime, 1);
        this.query(command);
    }
    /**
     * 查询
     *
     * @param command 查询语句
     * @return 查询结果
     */
    public QueryResult query(String command) {
        return influxdb.query(new Query(command, database));
    }
    /**
     * 插入
     *
     * @param measurement 表
     * @param tags        标签
     * @param fields      字段
     */
    public void insert(String measurement, Map<String, String> tags, Map<String, Object> fields) {
        Point.Builder builder = Point.measurement(measurement);
        builder.time(System.currentTimeMillis(), TimeUnit.MILLISECONDS);
        builder.tag(tags);
        builder.fields(fields);
        log.info("influxDB insert data:[{}]", builder.build().toString());
        influxdb.write(database, "", builder.build());
    }
}

对象封装:

@Data
@NoArgsConstructor
@AllArgsConstructor
public class Usage {
    private String time;
    private String serviceMethod;
    private String userId;
    private Integer count;
    private String url;
}

测试类:

@SpringBootTest
class InfluxDatabaseApplicationTests {
    @Autowired
    private InfluxDatabaseUtil influxDatabaseUtil;
    @Test
    void testInsert() throws InterruptedException {
        Map<String, String> tagsMap = new HashMap<>();
        Map<String, Object> fieldsMap = new HashMap<>();
        System.out.println("influxDB start time :" + System.currentTimeMillis());
        int i = 0;
        do {
            Thread.sleep(100);
            tagsMap.put("user_id", String.valueOf(i % 10));
            tagsMap.put("url", "http://www.baidu.com");
            tagsMap.put("service_method", "testInsert" + (i % 5));
            fieldsMap.put("count", i % 5);
            influxDatabaseUtil.insert("usage", tagsMap, fieldsMap);
            i++;
        } while (i < 50);
    }
    @Test
    void testQuery() {
        QueryResult query = influxDatabaseUtil.query("select * from usage limit 10");
        ArrayList<Object> lists = new ArrayList<>();
        query.getResults().forEach(result -> {
            result.getSeries().forEach(serie -> {
                List<List<Object>> values = serie.getValues();
                List<String> columns = serie.getColumns();
                lists.addAll(getQueryData(columns, values));
            });
        });
        System.out.println(lists.toString());
    }
    private List<Usage> getQueryData(List<String> columns, List<List<Object>> values) {
        List<Usage> lists = new ArrayList<>();
        for (List<Object> list : values) {
            Usage info = new Usage();
            BeanWrapperImpl bean = new BeanWrapperImpl(info);
            for (int i = 0; i < list.size(); i++) {
                String propertyName = setColumns(columns.get(i));
                // 字段名
                Object value = list.get(i);
                // 相应字段值
                bean.setPropertyValue(propertyName, value);
            }
            lists.add(info);
        }
        return lists;
    }
    /*** 转义字段 ***/
    private String setColumns(String column) {
        String[] cols = column.split("_");
        StringBuffer sb = new StringBuffer();
        for (int i = 0; i < cols.length; i++) {
            String col = cols[i].toLowerCase();
            if (i != 0) {
                String start = col.substring(0, 1).toUpperCase();
                String end = col.substring(1).toLowerCase();
                col = start + end;
            }
            sb.append(col);
        }
        return sb.toString();
    }
}

2.Feign接口调用InfluxDB API

2.1 依赖及配置

<dependency>
  <groupId>org.springframework.cloud</groupId>
  <artifactId>spring-cloud-starter-openfeign</artifactId>
  <version>2.2.6.RELEASE</version>
</dependency>
ribbon:
    ReadTimeout: 5000
    ConnectTimeout: 5000

2.2 代码实现

Use the InfluxDB API 文档有详细说明,以下是feign接口:

@FeignClient(name = "influxDbApi", url = "${spring.influx.url}")
public interface InfluxDbApi {
    /**
     * 查询数据库
     *
     * @param q  查询语句
     * @param db 数据库
     * @param u  用户名
     * @param p  密码
     * @return 查询结果
     * @throws Exception 可能出现的异常
     */
    @PostMapping("/query")
    String queryInfo(@RequestParam String db, @RequestParam String u, @RequestParam String p, @RequestParam String q) throws Exception;
}

调用测试类:

@Component
public class ApiTesting {
    @Autowired
    private InfluxDbApi influxDbApi;
    String test() throws Exception {
       /* Map<String, Object> param = new HashMap<>(8);
        param.put("q","CREATE DATABASE testDB");*/
        return influxDbApi.queryInfo("mydb", "admin", "admin", "select * from usage");
    }
}

测试接口:

@RestController
@Slf4j
public class ApiController {
    @Resource(name = "apiTesting")
    private ApiTesting apiTesting;
    @PostMapping("/test")
    public String get() throws Exception {
        log.info("------test------");
        return apiTesting.test();
    }
}
目录
相关文章
|
14天前
|
存储 监控 安全
数据库多实例的部署与配置方法
【10月更文挑战第23天】数据库多实例的部署和配置需要综合考虑多个因素,包括硬件资源、软件设置、性能优化、安全保障等。通过合理的部署和配置,可以充分发挥多实例的优势,提高数据库系统的运行效率和可靠性。在实际操作中,要不断总结经验,根据实际情况进行调整和优化,以适应不断变化的业务需求。
|
13天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个具有动态路由和菜单功能的前后端分离应用。首先,创建并配置 Spring Boot 项目,实现后端 API;然后,使用 Ant Design Pro Vue 创建前端项目,配置动态路由和菜单。通过具体案例,展示了如何快速搭建高效、易维护的项目框架。
92 62
|
14天前
|
负载均衡 网络协议 数据库
选择适合自己的数据库多实例负载均衡技术
【10月更文挑战第23天】选择适合自己的数据库多实例负载均衡技术需要全面考虑多种因素。通过深入的分析和评估,结合自身的实际情况,能够做出明智的决策,为数据库系统的高效运行提供有力保障。
|
14天前
|
存储 负载均衡 监控
数据库多实例的深入解析
【10月更文挑战第24天】数据库多实例是一种重要的数据库架构方式,它为数据库的高效运行和灵活管理提供了多种优势。在实际应用中,需要根据具体的业务需求和技术环境,合理选择和配置多实例,以充分发挥其优势,提高数据库系统的性能和可靠性。随着技术的不断发展和进步,数据库多实例技术也将不断完善和创新,为数据库管理带来更多的可能性和便利。
84 57
|
2天前
|
存储 SQL API
探索后端开发:构建高效API与数据库交互
【10月更文挑战第36天】在数字化时代,后端开发是连接用户界面和数据存储的桥梁。本文深入探讨如何设计高效的API以及如何实现API与数据库之间的无缝交互,确保数据的一致性和高性能。我们将从基础概念出发,逐步深入到实战技巧,为读者提供一个清晰的后端开发路线图。
|
4天前
|
Prometheus 监控 Java
深入探索:自制Agent监控API接口耗时实践
在微服务架构中,监控API接口的调用耗时对于性能优化至关重要。通过监控接口耗时,我们可以识别性能瓶颈,优化服务响应速度。本文将分享如何自己动手实现一个Agent来统计API接口的调用耗时,提供一种实用的技术解决方案。
13 3
|
7天前
|
监控 安全 应用服务中间件
微服务架构下的API网关设计策略与实践####
本文深入探讨了在微服务架构下,API网关作为系统统一入口点的设计策略、实现细节及其在实际应用中的最佳实践。不同于传统的摘要概述,本部分将直接以一段精简的代码示例作为引子,展示一个基于NGINX的简单API网关配置片段,随后引出文章的核心内容,旨在通过具体实例激发读者兴趣,快速理解API网关在微服务架构中的关键作用及实现方式。 ```nginx server { listen 80; server_name api.example.com; location / { proxy_pass http://backend_service:5000;
|
11天前
|
JavaScript 安全 Java
如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能
本文介绍了如何使用 Spring Boot 和 Ant Design Pro Vue 构建一个前后端分离的应用框架,实现动态路由和菜单功能。首先,确保开发环境已安装必要的工具,然后创建并配置 Spring Boot 项目,包括添加依赖和配置 Spring Security。接着,创建后端 API 和前端项目,配置动态路由和菜单。最后,运行项目并分享实践心得,帮助开发者提高开发效率和应用的可维护性。
28 2
|
12天前
|
XML API 网络架构
深入理解RESTful API设计原则与实践
【10月更文挑战第26天】在数字化浪潮中,API(应用程序编程接口)成为连接不同软件组件的桥梁。本文将深入浅出地探讨如何根据REST(Representational State Transfer)原则设计高效、易于维护和扩展的API,同时分享一些实用的代码示例,帮助开发者构建更加健壮和用户友好的服务。
|
14天前
|
缓存 负载均衡 监控
数据库多实例的负载均衡技术深入
【10月更文挑战第23天】数据库多实例负载均衡技术是确保数据库系统高效运行的重要手段。通过合理选择负载均衡策略、实时监控实例状态、不断优化调整,能够实现资源的最优分配和系统性能的提升。在实际应用中,需要根据具体情况灵活运用各种负载均衡技术,并结合其他相关技术,以满足不断变化的业务需求。