当前位置: 首页 > news >正文

SpringBoot整合MQTT实战:基于EMQX构建高可靠物联网通信,从零到一实现设备云端双向对话

一、引言

随着物联网(IoT)技术的快速发展,MQTT(Message Queuing Telemetry Transport)协议因其轻量级、低功耗和高效的特点,已成为物联网设备通信的事实标准。本文将详细介绍如何使用SpringBoot框架整合MQTT协议,基于开源MQTT代理EMQX实现设备与服务器之间的双向通信。

二、技术选型与环境准备

2.1 技术栈介绍

  • SpringBoot 2.7.x:简化Spring应用初始搭建和开发过程

  • EMQX 5.0:开源的大规模分布式MQTT消息服务器

  • Eclipse Paho:流行的MQTT客户端库

  • Lombok:简化Java Bean编写

2.2 环境准备

  1. 安装EMQX服务器(可使用Docker快速部署):

    docker run -d --name emqx -p 1883:1883 -p 8083:8083 -p 8084:8084 -p 8883:8883 -p 18083:18083 emqx/emqx:5.0.14

  2. 确保Java开发环境(JDK 11+)和Maven已安装

三、SpringBoot项目集成MQTT

3.1 创建SpringBoot项目并添加依赖

pom.xml中添加必要的依赖:

<dependencies><!-- SpringBoot Starter --><dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter</artifactId></dependency><!-- MQTT Paho Client --><dependency><groupId>org.eclipse.paho</groupId><artifactId>org.eclipse.paho.client.mqttv3</artifactId><version>1.2.5</version></dependency><!-- Lombok --><dependency><groupId>org.projectlombok</groupId><artifactId>lombok</artifactId><optional>true</optional></dependency><!-- JSON处理 --><dependency><groupId>com.fasterxml.jackson.core</groupId><artifactId>jackson-databind</artifactId></dependency>
</dependencies>

3.2 配置MQTT连接参数

application.yml中添加配置:

mqtt:broker-url: tcp://localhost:1883username: emqxpassword: publicclient-id: springboot-serverdefault-topic: device/statustimeout: 30keepalive: 60qos: 1clean-session: true

创建配置类MqttProperties.java

@Data
@Configuration
@ConfigurationProperties(prefix = "mqtt")
public class MqttProperties {private String brokerUrl;private String username;private String password;private String clientId;private String defaultTopic;private int timeout;private int keepalive;private int qos;private boolean cleanSession;
}

3.3 实现MQTT客户端配置

创建MqttConfiguration.java

@Configuration
@RequiredArgsConstructor
public class MqttConfiguration {private final MqttProperties mqttProperties;@Beanpublic MqttConnectOptions mqttConnectOptions() {MqttConnectOptions options = new MqttConnectOptions();options.setServerURIs(new String[]{mqttProperties.getBrokerUrl()});options.setUserName(mqttProperties.getUsername());options.setPassword(mqttProperties.getPassword().toCharArray());options.setConnectionTimeout(mqttProperties.getTimeout());options.setKeepAliveInterval(mqttProperties.getKeepalive());options.setCleanSession(mqttProperties.isCleanSession());options.setAutomaticReconnect(true);return options;}@Beanpublic IMqttClient mqttClient() throws MqttException {IMqttClient client = new MqttClient(mqttProperties.getBrokerUrl(), mqttProperties.getClientId(), new MemoryPersistence());client.connect(mqttConnectOptions());return client;}
}

3.4 实现MQTT消息发布服务

创建MqttPublisher.java

@Service
@RequiredArgsConstructor
@Slf4j
public class MqttPublisher {private final IMqttClient mqttClient;private final MqttProperties mqttProperties;public void publish(String topic, String payload) throws MqttException {if (!mqttClient.isConnected()) {mqttClient.reconnect();}MqttMessage message = new MqttMessage(payload.getBytes());message.setQos(mqttProperties.getQos());message.setRetained(true);mqttClient.publish(topic, message);log.info("MQTT message published to topic: {}, payload: {}", topic, payload);}public void publish(String payload) throws MqttException {publish(mqttProperties.getDefaultTopic(), payload);}
}

3.5 实现MQTT消息订阅服务

创建MqttSubscriber.java

@Service
@RequiredArgsConstructor
@Slf4j
public class MqttSubscriber {private final IMqttClient mqttClient;private final MqttProperties mqttProperties;@PostConstructpublic void init() throws MqttException {subscribe(mqttProperties.getDefaultTopic());}public void subscribe(String topic) throws MqttException {if (!mqttClient.isConnected()) {mqttClient.reconnect();}mqttClient.subscribe(topic, mqttProperties.getQos(), this::handleMessage);log.info("Subscribed to MQTT topic: {}", topic);}private void handleMessage(String topic, MqttMessage message) {String payload = new String(message.getPayload());log.info("Received MQTT message from topic: {}, payload: {}", topic, payload);// 这里可以添加业务逻辑处理接收到的消息processMessage(topic, payload);}private void processMessage(String topic, String payload) {// 示例:解析JSON格式的消息try {ObjectMapper mapper = new ObjectMapper();JsonNode jsonNode = mapper.readTree(payload);// 根据不同的topic和payload内容进行业务处理if (topic.startsWith("device/status")) {handleDeviceStatus(jsonNode);} else if (topic.startsWith("device/control")) {handleDeviceControl(jsonNode);}} catch (JsonProcessingException e) {log.error("Failed to parse MQTT message payload: {}", payload, e);}}private void handleDeviceStatus(JsonNode jsonNode) {// 处理设备状态上报String deviceId = jsonNode.get("deviceId").asText();String status = jsonNode.get("status").asText();log.info("Device {} status updated to: {}", deviceId, status);}private void handleDeviceControl(JsonNode jsonNode) {// 处理设备控制指令响应String deviceId = jsonNode.get("deviceId").asText();String command = jsonNode.get("command").asText();String result = jsonNode.get("result").asText();log.info("Device {} executed command {} with result: {}", deviceId, command, result);}
}

四、实现双向通信

4.1 服务器向设备发送控制指令

创建REST API接口用于发送控制指令:

@RestController
@RequestMapping("/api/device")
@RequiredArgsConstructor
@Slf4j
public class DeviceController {private final MqttPublisher mqttPublisher;@PostMapping("/control")public ResponseEntity<String> sendControlCommand(@RequestBody DeviceCommand command) {try {ObjectMapper mapper = new ObjectMapper();String payload = mapper.writeValueAsString(command);String topic = "device/control/" + command.getDeviceId();mqttPublisher.publish(topic, payload);return ResponseEntity.ok("Control command sent successfully");} catch (Exception e) {log.error("Failed to send control command", e);return ResponseEntity.status(HttpStatus.INTERNAL_SERVER_ERROR).body("Failed to send control command: " + e.getMessage());}}@Data@NoArgsConstructor@AllArgsConstructorpublic static class DeviceCommand {private String deviceId;private String command;private Map<String, Object> params;}
}

4.2 设备模拟客户端

为了测试双向通信,我们可以创建一个简单的设备模拟客户端:

@Component
@Slf4j
public class DeviceSimulator {private final MqttPublisher mqttPublisher;private final MqttProperties mqttProperties;private IMqttClient deviceClient;public DeviceSimulator(MqttPublisher mqttPublisher, MqttProperties mqttProperties) {this.mqttPublisher = mqttPublisher;this.mqttProperties = mqttProperties;initDeviceClient();}private void initDeviceClient() {try {String deviceId = "device-" + UUID.randomUUID().toString().substring(0, 8);deviceClient = new MqttClient(mqttProperties.getBrokerUrl(), deviceId, new MemoryPersistence());MqttConnectOptions options = new MqttConnectOptions();options.setUserName(mqttProperties.getUsername());options.setPassword(mqttProperties.getPassword().toCharArray());options.setAutomaticReconnect(true);deviceClient.connect(options);// 订阅控制主题String controlTopic = "device/control/" + deviceId;deviceClient.subscribe(controlTopic, (topic, message) -> {String payload = new String(message.getPayload());log.info("Device received control command: {}", payload);// 模拟设备执行命令并返回响应executeCommand(payload, deviceId);});// 模拟设备定期上报状态simulatePeriodicStatusReport(deviceId);} catch (MqttException e) {log.error("Failed to initialize device simulator", e);}}private void executeCommand(String payload, String deviceId) {try {ObjectMapper mapper = new ObjectMapper();JsonNode jsonNode = mapper.readTree(payload);String command = jsonNode.get("command").asText();// 模拟命令执行Thread.sleep(1000); // 模拟执行耗时// 构造响应ObjectNode response = mapper.createObjectNode();response.put("deviceId", deviceId);response.put("command", command);response.put("result", "success");response.put("timestamp", System.currentTimeMillis());// 发布响应String responseTopic = "device/control/response/" + deviceId;mqttPublisher.publish(responseTopic, response.toString());} catch (Exception e) {log.error("Failed to execute command", e);}}private void simulatePeriodicStatusReport(String deviceId) {ScheduledExecutorService executor = Executors.newSingleThreadScheduledExecutor();executor.scheduleAtFixedRate(() -> {try {ObjectMapper mapper = new ObjectMapper();ObjectNode status = mapper.createObjectNode();status.put("deviceId", deviceId);status.put("status", "online");status.put("cpuUsage", Math.random() * 100);status.put("memoryUsage", 30 + Math.random() * 50);status.put("timestamp", System.currentTimeMillis());String topic = "device/status/" + deviceId;mqttPublisher.publish(topic, status.toString());} catch (Exception e) {log.error("Failed to send status report", e);}}, 0, 10, TimeUnit.SECONDS);}
}

五、测试与验证

5.1 测试设备状态上报

  1. 启动SpringBoot应用

  2. 观察日志输出,应该能看到设备模拟客户端定期上报状态信息

5.2 测试服务器控制指令

使用Postman或curl发送控制指令:

curl -X POST http://localhost:8080/api/device/control \
-H "Content-Type: application/json" \
-d '{"deviceId": "device-123456","command": "restart","params": {"delay": 5}
}'

5.3 验证双向通信

  1. 服务器发送控制指令到特定设备

  2. 设备接收指令并执行

  3. 设备发送执行结果回服务器

  4. 服务器接收并处理设备响应

六、高级功能扩展

6.1 消息持久化与QoS级别

  • QoS 0:最多一次,消息可能丢失

  • QoS 1:至少一次,消息不会丢失但可能重复

  • QoS 2:恰好一次,消息不丢失且不重复

根据业务需求选择合适的QoS级别:

// 在发布消息时设置QoS
message.setQos(2); // 使用最高级别的QoS

6.2 安全配置

  1. 启用TLS加密:

mqtt:broker-url: ssl://localhost:8883
  1. 配置EMQX的ACL规则,限制客户端权限

6.3 集群部署

对于生产环境,可以部署EMQX集群:

# 启动第一个节点
docker run -d --name emqx1 -p 1883:1883 -p 8081:8081 -e EMQX_NODE_NAME=emqx@node1.emqx.io -e EMQX_CLUSTER__DISCOVERY=static -e EMQX_CLUSTER__STATIC__SEEDS="emqx@node1.emqx.io,emqx@node2.emqx.io" emqx/emqx:5.0.14# 启动第二个节点
docker run -d --name emqx2 -p 1884:1883 -p 8082:8081 -e EMQX_NODE_NAME=emqx@node2.emqx.io -e EMQX_CLUSTER__DISCOVERY=static -e EMQX_CLUSTER__STATIC__SEEDS="emqx@node1.emqx.io,emqx@node2.emqx.io" emqx/emqx:5.0.14

6.4 消息桥接与WebHook

通过EMQX的桥接功能,可以将消息转发到其他MQTT服务器或Kafka等消息队列。也可以通过WebHook将消息推送到HTTP服务。

七、总结

本文详细介绍了如何使用SpringBoot整合MQTT协议,基于EMQX实现设备与服务器之间的双向通信。主要内容包括:

  1. SpringBoot项目中集成MQTT客户端

  2. 实现消息发布和订阅功能

  3. 设计双向通信机制

  4. 设备模拟与测试验证

  5. 高级功能扩展建议

这种架构非常适合物联网场景,能够支持海量设备连接和实时消息通信。开发者可以根据实际业务需求,在此基础上进行扩展和优化,构建稳定可靠的物联网平台。

八、参考资料

  1. EMQX官方文档:Introduction | EMQX 5.0 Docs

  2. Eclipse Paho项目:Eclipse Paho | The Eclipse Foundation

  3. MQTT协议规范:MQTT Version 3.1.1

  4. Spring Boot官方文档:Spring Boot

相关文章:

SpringBoot整合MQTT实战:基于EMQX构建高可靠物联网通信,从零到一实现设备云端双向对话

一、引言 随着物联网(IoT)技术的快速发展&#xff0c;MQTT(Message Queuing Telemetry Transport)协议因其轻量级、低功耗和高效的特点&#xff0c;已成为物联网设备通信的事实标准。本文将详细介绍如何使用SpringBoot框架整合MQTT协议&#xff0c;基于开源MQTT代理EMQX实现设…...

Windows更新暂停七天关键注册表

环境&#xff1a;windows10 工具&#xff1a;procmon 下载地址&#xff1a;https://learn.microsoft.com/zh-cn/sysinternals/downloads/procmon 监控截图&#xff1a; 界面截图&#xff1a; 注&#xff1a; 1.北京时间差8小时 2.至少是从第二天恢复&#xff0c;即至少暂停…...

小白学习java第18天(上):spring

Spring &#xff1a;是一个轻量级&#xff08;一个小依赖就可以实现还不是轻量级&#xff09;的控制反转&#xff08;IOC&#xff09;和面向切面编程&#xff08;AOP&#xff09;的框架&#xff01; 优点&#xff1a; 1.Spring 是一个开源免费的框架&#xff08;容器&#xf…...

用Array.from实现创建一个1-100的数组

一、代码实现 let arr Array.from({length: 100}, (_, i) > i 1); 二、代码分析 1、Array.from(arrayLike, mapFn) &#xff08;1&#xff09;arrayLike 类数组对象&#xff08;如 { length: 100 }&#xff09;本身没有索引属性&#xff08;如 0: undefined, 1: undefi…...

什么是物联网 IoT 平台?

目录 物联网IoT平台的定义 物联网 IoT 平台发展历程 物联网IoT平台数据的特征 物联网IoT平台的处理流程 专为物联网 IoT 平台处理而生的时序数据库 物联网 IoT 平台时序数据处理面临的挑战及解决方案 收益与价值 物联网 IoT 平台企业案例 至数摇光 x TDengine 华自科技…...

PostgREST:无需后端 快速构建RESTful API服务

在现代 Web 开发中&#xff0c;API 已成为连接前后端的核心桥梁&#xff0c;传统的做法是通过后端框架来构建API接口&#xff0c;然后由前后端人员进行联调。 PostgREST是基于无服务器的一种实现方案&#xff0c;允许开发者将PostgreSQL数据库直接暴露为RESTful API&#xff0…...

3天北京旅游规划

北京 第一天应该集中在故宫和市中心区域&#xff0c;比如天安门、人民广场。这样可以体验到北京的历史和政治文化。午餐推荐烤鸭&#xff0c;因为这可是北京的特色。下午可以安排南锣鼓巷&#xff0c;既有古色古香的胡同&#xff0c;又有丰富的美食选择。 第二天的话&#xff0…...

MySQL--day1--数据库概述

&#xff08;以下内容全部来自上述课程&#xff09; 概述 1. 为什么要用数据库 持久化&#xff1a;内存中的数据断电之后就不存在了&#xff0c;所以需要持久化–>需要相关介质。 其中的一个介质就是数据库&#xff1a;存储数据量大、存储数据类型多 2. 数据库与数据库…...

[思维模式-38]:看透事物的关系:什么是事物的关系?事物之间的关系的种类?什么是因果关系?如何通过数学的方式表达因果关系?

一、什么是事物的关系&#xff1f; 事物的关系是指不同事物之间存在的各种联系和相互作用&#xff0c;它反映了事物之间的相互依存、相互影响、相互制约等特性。以下从不同维度为你详细阐述&#xff1a; 1、关系的类型 因果关系 定义&#xff1a;一个事件&#xff08;原因&a…...

图像识别与 OCR 应用实践

图像识别是一种让计算机具备“看”与“理解”图像能力的人工智能技术&#xff0c;其目标是从图像或视频中提取有意义的信息&#xff0c;如物体、人物、场景或文字。在现实生活中&#xff0c;这项技术被广泛应用于面部识别、自动驾驶、安防监控、医疗诊断、图像搜索等多个领域。…...

深入理解卷积神经网络:从基础原理到实战应用

在人工智能领域&#xff0c;卷积神经网络&#xff08;Convolutional Neural Network&#xff0c;简称 CNN&#xff09;凭借其强大的图像识别、处理能力&#xff0c;成为深度学习中不可或缺的技术。无论是自动驾驶汽车识别道路标志&#xff0c;还是医学影像分析辅助疾病诊断&…...

51单片机——交通指示灯控制器设计

设计目标 1、设计一交通灯控制&#xff0c;控制东西方向的红、黄、绿灯和南北方向的红、黄、绿灯。 2、可手动控制和自动控制&#xff0c;设置两个输入控制开关。 手动/自动开关&#xff0c;通过P11的按键输入控制 3、手动&#xff1a;设置开关P11&#xff0c;两种情况&#x…...

vue2 头像上传+裁剪组件封装

背景&#xff1a;最近在进行公司业务开发时&#xff0c;遇到了头像上传限制尺寸的需求&#xff0c;即限制为一寸证件照&#xff08;宽295像素&#xff0c;高413像素&#xff09;。 用到的第三方库&#xff1a; "vue-cropper": "^0.5.5" 完整组件代码&…...

面向对象设计模式之代理模式详解

文章目录 面向对象设计模式之代理模式详解面向对象思想&#xff1a;现代软件开发的基石代理模式&#xff1a;巧妙的中间层设计JavaScript 语法点与代理模式的结合JavaScript 实现代理模式示例代理模式的应用场景 面向对象设计模式之代理模式详解 在现代软件开发的浩瀚领域中&a…...

Leetcode209做题笔记

力扣209 题目分析&#xff1a;想象一个窗口遍历着这个数组&#xff0c;不断扩大右边界&#xff0c;让r。往窗口中添加数字&#xff1a; 此时我们找到了这个窗口&#xff0c;它的和满足了大于等于target的条件&#xff0c;题目让我求最短的&#xff0c;那么我们就尝试来缩短它&…...

SVG 知识详解:从入门到精通

SVG 知识详解&#xff1a;从入门到精通 作为一名前端开发者&#xff0c;我经常会被SVG的魅力所折服。这种基于XML的矢量图形格式&#xff0c;不仅能完美适配各种屏幕分辨率&#xff0c;还能通过CSS和JavaScript进行灵活控制。今天&#xff0c;就让我们一起来深入探索SVG的世界…...

编译openssl源码

openssl版本 1.1.1c windows 安装环境 perl 先安装perl&#xff0c;生成makefile需要 https://strawberryperl.com/releases.html nasm nasm 也是生成makefile需要 https://www.nasm.us/ 安装完perl输入一下nasm&#xff0c;看看能不能找到&#xff0c;找不到的话需要配…...

土壤温湿盐分传感器用于节水农业灌溉引领者三针设计原理便于安装维护

土壤温度部分是由精密铂电阻和高精度变送器两部分组成。变送器部分由电源模块、温度传感模块、变送模块、温度补偿模块及数据处理模块等组成&#xff0c;彻底解决铂电阻因自身特点导入的测量误差&#xff0c;变送器内有零漂电路和温度补偿电路&#xff0c;对使用环境有较高的适…...

Kotlin Compose 与传统 Android UI 开发对比

在移动应用开发领域,Android 开发一直是技术演进的前沿阵地,而 UI 开发作为用户与应用交互的核心环节,其技术体系的变革更是备受瞩目。 技术演进背景 Android UI 开发体系发展脉络 原生 View 体系阶段 在早期的 Android 开发中,原生 View 体系占据了主导地位。开发者通…...

docker-compose——安装redis

文章目录 一、编写docker-compose.yaml文件二、编写redis.conf文件三、启动docker-compose 一、编写docker-compose.yaml文件 version: 3.3 services:redis:image: redis:latestcontainer_name: redisrestart: alwaysports:- 6379:6379volumes:- ./redis/data:/data- ./redis/…...

MFC 调用海康相机进行软触发

初始化相机类文件 #pragma once #include "MvCameraControl.h" class CMvCamera { public:CMvCamera();~CMvCamera();//初始化相机int InitCamera();int SaveCurrentImage(CString filePath);//关闭相机void CloseCamera();//设置int SetEnumValue(IN const char* s…...

第二章 变量和运算符

主要内容 关键字和标识符变量和常量八大基本数据类型Scanner键盘输入基本数据类型的类型转换算术运算符赋值运算符扩展赋值运算符比较运算符逻辑运算符三目运算符运算符的优先级别 学习目标 知识点要求关键字和标识符理解变量和常量掌握八大基本数据类型掌握Scanner键盘输入…...

【starrocks】StarRocks 常见 HTTP 操作与导入错误排查指南

文章目录 一、Stream Load&#xff1a;通过 HTTP 导入数据二、导入状态查询三、取消导入任务四、节点状态监控查看所有 Backend 状态&#xff1a;查看所有 Frontend 状态&#xff1a; 五、导入失败的排查方式1. 查询导入任务状态2. 下载详细错误日志3. 查看 FE/BE 节点日志FE 日…...

网络协议分析 实验七 FTP、HTTP、DHCP

文章目录 实验7.1 FTP协议练习二 使用浏览器登入FTP练习三 在窗口模式下&#xff0c;上传/下传数据文件实验7.2 HTTP(Hyper Text Transfer Protocol)练习二 页面提交练习三 访问比较复杂的主页实验7.3 DHCP(Dynamic Host Configuration Protocol) 实验7.1 FTP协议 dir LIST&…...

ET ProcessInnerSender类(实体) 分析

ProcessInnerSender 作用是进程内部发送Actor消息 字段 TIMEOUT_TIME 超时时间RpcId 用来累加requestCallback 存储RPC的回调事件list 用来获取MessageQueue中的Actor消息 方法 Awake 初始化在MessageQueue中注册待处理的消息队列Destroy 移除在MessageQueue中的消息队列U…...

远程连接工具

绿色轻便ToDesk https://www.todesk.com/download.html 向日葵 https://sunlogin.oray.com/download...

MySQL库级管理:数据库管理与存储引擎剖析

引言 各位数据库爱好者们好&#xff01;今天我们要深入探讨MySQL数据库的基本操作&#xff0c;这是每位开发者必须掌握的"内功心法" &#x1f4aa;。无论你是刚接触MySQL的小白&#xff0c;还是需要复习基础的老手&#xff0c;这篇教程都将带你系统学习数据库的核心…...

MongoDB 的核心概念(文档、集合、数据库、BSON)是什么?

MongoDB 是一个面向文档的数据库&#xff0c;它的核心概念与传统的关系型数据库&#xff08;RDBMS&#xff09;有所不同。以下是它的四个主要核心概念&#xff1a; 文档 (Document) 定义&#xff1a; 文档是 MongoDB 中的基本数据单元。它类似于关系型数据库中的一行记录&#…...

占位符读取标准输入缓冲区规则

1、如果标准输入缓冲区中的前若干个字符都是空白字符&#xff0c;%s&#xff0c;%d&#xff0c;%f都能直接跳过并且从第一个非空白字符开始读取&#xff0c;但%c不能&#xff0c;而是直接读取。 2、%s遇到空白字符时停止&#xff0c;不会读取遇到的空白字符。 3、%d遇到非数字…...

使用Docker部署MongoDB

使用Docker部署MongoDB 使用Docker部署MongoDB是一种快速、便捷的方式&#xff0c;以下是详细步骤&#xff1a; 1. 基本部署 拉取MongoDB镜像 docker pull mongo:latest运行MongoDB容器&#xff08;最简单方式&#xff09; docker run --name mongodb -d -p 27017:27017 m…...

如何通过命令提示符(CMD)检查虚拟化是否已启用

想确认 Windows 11 或 10 电脑或笔记本上的虚拟化是否已启用,可以使用命令提示符或 PowerShell 中的 systeminfo 命令。之前已经介绍过使用图形界面的检查方法。在大多数现代系统中,虚拟化默认在 BIOS 中启用,但我们无需打开 BIOS/UEFI 固件菜单即可确认这一点。 虚拟化是一…...

【氮化镓】AlGaN合金中成分相关的辐射响应

2025年,美国宾夕法尼亚州立大学Miaomiao Jin等人基于分子动力学模拟方法,研究了AlGaN合金中成分依赖的辐射响应。研究结果表明,AlGaN合金的辐射损伤特性与铝含量密切相关:随铝含量增加,单次碰撞事件产生的缺陷减少,但由于累积效应,富铝系统更易形成扩展间隙缺陷簇,导致…...

『 测试 』软件测试全流程与Bug管理核心要点解析

文章目录 1 软件测试生命周期2 Bug2.1 Bug 的概念2.2 提出清晰的 Bug2.3 Bug 级别2.4 Bug 的生命周期2.5 作为测试人员与开发人员发生冲突怎么办 1 软件测试生命周期 软件测试贯穿于软件的整个生命周期; 需求分析 测试前需要对需求进行分析, 分析通常站在三个角度去考虑, 即用…...

【springcloud学习(dalston.sr1)】使用Feign实现接口调用(八)

该系列项目整体介绍及源代码请参照前面写的一篇文章【springcloud学习(dalston.sr1)】项目整体介绍&#xff08;含源代码&#xff09;&#xff08;一&#xff09; &#xff08;一&#xff09;Feign的理解 前面文章【springcloud学习(dalston.sr1)】服务消费者通过restTemplat…...

嵌入式Linux Qt开发:2、Qt creator简单配置、Qt Designer使用以及信号槽机制使用

一、前言 Qt creator比较轻量&#xff0c;而且是Qt自带的IDE&#xff0c;基本可以开箱即用&#xff0c;个人使用起来感觉还是比较舒服的&#xff0c;并且其自带的FakeVim也可以做一些Vim的配置&#xff0c;其主界面可以简单配置显示很多的窗口&#xff0c;让开发更加顺畅。 Q…...

【Vue 3 + Vue Router 4】如何正确重置路由实例(resetRouter)——避免“VueRouter is not defined”错误

在使用 Vue 3 和 Vue Router 4 开发中大型 SPA 应用时&#xff0c;我们经常会遇到需要动态添加或删除路由的场景。尤其是在权限控制和用户登出后重置路由的需求中&#xff0c;正确地实现 resetRouter 非常关键。 然而&#xff0c;许多开发者在迁移或初始化项目时&#xff0c;会…...

企业内部通讯,企业级即时通讯软件选择

企业内部的沟通往往涉及大量敏感信息&#xff0c;如商业机密、财务数据、客户信息等。BeeWorks IM即时通讯平台采用全私有化部署&#xff0c;企业可以将服务器部署在自己的数据中心或私有云环境中&#xff0c;确保所有数据的存储和传输都在企业可控的网络内完成。这种部署方式从…...

300. 最长递增子序列

理解最长递增子序列&#xff08;LIS&#xff09;是解决该问题的关键。子序列是从给定数组中按顺序选取的元素序列&#xff0c;例如数组 [1, 2, 3, 4, 5] 的子序列可以是 [2, 3, 4]。需要注意的是&#xff0c;子序列的元素在原数组中不一定是连续的。因此&#xff0c;最长递增子…...

MongoDB入门

1.MongoDB 基本概念详解 2.MongoDB 快速实战 3.MongoDB 核心操作与原理详解 Mongo 是 humongous 的中间部分&#xff0c;在英文里是“巨大无比”的意思。所以 MongoDB 可以翻译 成“巨大无比的数据库”&#xff0c;更优雅的叫法是“海量数据库”。Mongodb是一款非关系型数据库…...

MySQL基础原理

目录 一、MySQL架构 1、四层架构 2、MySQL运行机制 二、MySQL存储引擎 1、不同存储引擎对比 2、InnoDB存储结构 2.1 内存结构 2.2 磁盘结构 3、日志先行策略 3.1 核心思想 3.2 关键组件与流程 3.3 数据安全保证 3.3.1 崩溃恢复 3.3.2 持久性保障 一、MySQL架构 …...

Python刷题练习

文章目录 1.寻找相同字串2.密钥格式化3.五键键盘的输出4.单词重量5.输出指定字母在字符串的中的索引6.污染水域7.九宫格按键输入8.任务最优调度9.高效的任务规划 1.寻找相同字串 题目描述: 给你两个字符串t和p&#xff0c;要求从t中找到一个和p相同的连续子串&#xff0c;并输…...

基于GPUGEEK 平台进行深度学习

一、平台简介 GPUGEEK 是一个专注于提供 GPU 算力租赁服务的平台&#xff0c;在人工智能与深度学习领域为用户搭建起便捷的算力桥梁。它整合了丰富多样的 GPU 资源&#xff0c;涵盖 RTX - 4090、RTX - 3090、A100 - PCIE 等多种型号&#xff0c;满足不同用户在模型训练、数据处…...

基于Matlab的非线性Newmark法用于计算结构动力响应

基于Matlab的非线性Newmark法用于计算结构动力响应&#xff0c;主要针对材料非线性或几何非线性问题。 ​1. Newmark法基本原理​ Newmark法是一种隐式时间积分方法&#xff0c;通过预估-校正步骤更新位移、速度和加速度&#xff1a; ​预测步​&#xff1a; un1​un​Δtvn​…...

Oracle — PL-SQL

介绍 Oracle PL/SQL是专为Oracle数据库设计的过程化编程语言&#xff0c;深度融合SQL语句与结构化编程逻辑&#xff0c;旨在高效处理复杂数据操作与业务规则。其核心特征为“块结构”&#xff0c;程序由声明、执行、异常处理三部分组成&#xff0c;支持模块化开发&#xff0c;显…...

第七节第二部分:接口的综合案例

案例分析 代码&#xff1a; Student类 package com.Interface_Demo;public class Student {private String name;private char sex;private double score;public Student() {}public Student(String name, char sex, double score) {this.name name;this.sex sex;this.scor…...

【AI古风美学渲染】:淡雅光影中的细腻呈现

“顶作AI”作为国内首个深度融合中文语义的生成式AI平台&#xff0c;以近百亿级参数的Lens跨模态模型为核心&#xff0c;开创了“自然语言即生产力”的创作模式。该平台突破传统工具对专业术语的依赖&#xff0c;用户仅需输入如“水墨风格的山间庭院&#xff0c;晨雾中若隐若现…...

JVM学习专题(二)内存模型深度剖析

目录 1.JVM结构体系 ​编辑 2.跨平台特性 3.JVM整体结构及内存模型 1.栈内存 1、栈帧&#xff1a; 1.局部变量表 2.操作数栈 3.动态链接 4.方法出口 2、创建对象 2.程序计数器&#xff1a; 3.方法区 ​4.堆 5.本地方法区 6.总结 1.JVM结构体系 JDK、JRE 和 JVM…...

Prometheus 的介绍与部署(入门)

一、什么是Prometheus&#xff1b; 1.介绍 Prometheus 是一个功能强大的监控工具&#xff0c;适用于各种环境。通过简单的安装和配置&#xff0c;可以快速实现对系统和服务的监控。无论是单机环境、容器化环境还是 Kubernetes 集群&#xff0c;Prometheus 都能提供灵活…...

JavaSwing之-JDialog

JavaSwing之-JDialog JDialog 是 Java Swing 中用于创建对话框窗口的容器类&#xff0c;继承自 Dialog 类&#xff08;AWT&#xff09;&#xff0c;常用于显示临时信息、获取用户输入或执行模态操作。它是 javax.swing.JDialog 包中的类。 与 JFrame 不同的是&#xff0c;JDia…...

配置Nginx解决http host头攻击漏洞【详细步骤】

前言 大概内容&#xff1a; 安全系统渗透测试出host头攻击漏洞&#xff0c;下面是解决步骤&#xff0c;本人已测过无问题。 server_name aaabbb.com; if ($http_Host !~* ^127.0.0.1|aaabbb.com|localhost$){return 403;}...