避坑指南:Spring Boot3整合MQTT时最容易踩的5个坑(含解决方案)

springboot + MQTTv3 文章目录springboot + MQTTv3引入相关依赖期待效果以下相关代码,全部贴出MqttAutoConfigurationMqttTemplateMqttClientSubscribeManagerMqttSubscriberresolver相关类工具类注解类集合辅助类集合 springboot + MQTTv3 ​ 最近项目使用到 MQTT,在引入 mica-mqtt 尝试并发发送消息出现消息丢失的情况,QoS =0,1,2 存在消息丢失情况,QoS=2最严重,所以只好切换到 org.ec 阅读详情

Spring Boot 3 整合 MQTT 实战:开发者必须绕开的五个深坑与精解方案

如果你正在将 MQTT 协议集成到你的 Spring Boot 3 应用中,并且已经走过了基础的 @Configuration 和 @ServiceActivator 配置阶段,那么这篇文章正是为你准备的。网络上充斥着“从零开始”的教程,但真正让项目从“能跑”到“跑得稳”的,往往是那些配置文件中没有写明、日志里语焉不详的细节问题。连接时好时坏、消息神秘丢失、服务重启后订阅失效……这些才是真实生产环境中的常态。今天,我们不谈基础配置,只聚焦于那些最容易让开发者栽跟头的“坑”,并为你提供经过实战检验的解决方案。无论你是构建物联网平台、实时消息推送系统,还是任何需要轻量级发布/订阅模式的场景,避开这些陷阱,你的集成之路会顺畅得多。

1. 连接管理与断线重连:不仅仅是配置一个超时时间

很多教程会告诉你设置 MqttConnectOptions 里的 connectionTimeout 和 keepAliveInterval,仿佛这就能一劳永逸。但在生产环境中,网络抖动、服务端重启、中间件负载过高都是家常便饭。一个健壮的客户端,必须能优雅地处理断线并自动重连。

第一个深坑:静态配置的客户端ID与“清洁会话”的冲突。 你可能会在配置类里写死一个 clientId,比如 “my-springboot-app”,并且设置了 cleanSession=true。这看起来没问题,直到你的应用实例需要水平扩展。多个实例使用相同的 Client ID 连接 Broker,会导致前一个连接被强制踢下线。更隐蔽的问题是,如果 cleanSession=false(希望服务端持久化会话),但你的客户端ID在重启后发生了变化,那么服务端存储的未送达消息(QoS 1/2)和订阅信息将无法正确恢复。

提示:MQTT 协议中,Client ID 是会话(Session)的唯一标识。cleanSession 标志决定了连接断开后,服务器是否保留这个会话。

解决方案:动态化与唯一化客户端标识。

不要硬编码 Client ID。一个更可靠的策略是结合应用名、主机标识和随机数来生成。在 Spring 环境中,我们可以利用应用上下文和环境变量。

@Configuration
@ConfigurationProperties(prefix = "mqtt")
@Data
public class MqttConfig {
    private String hostUrl;
    private String clientIdPrefix; // 改为前缀配置,如 “iot-gateway-”
    // ... 其他配置

    @Bean
    public MqttPahoClientFactory mqttClientFactory() {
        DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
        MqttConnectOptions options = new MqttConnectOptions();

        // 动态生成唯一 Client ID
        String generatedClientId = generateUniqueClientId();
        options.setServerURIs(new String[]{hostUrl});
        // ... 设置其他选项

        factory.setConnectionOptions(options);
        return factory;
    }

    private String generateUniqueClientId() {
        String hostName;
        try {
            hostName = InetAddress.getLocalHost().getHostName();
        } catch (UnknownHostException e) {
            hostName = "unknown-host";
        }
        // 使用前缀+主机名+进程ID+时间戳,确保唯一性
        return String.format("%s-%s-%d-%d",
                clientIdPrefix,
                hostName,
                ProcessHandle.current().pid(),
                System.currentTimeMillis() % 10000); // 加入时间戳防止瞬时重复
    }
}

对于入站适配器(消费者),也需要使用不同的 Client ID 后缀,避免与出站处理器冲突。

第二个深坑:默认重连机制的缺失。 MqttPahoClientFactory 和 MqttPahoMessageDrivenChannelAdapter 默认并不提供自动重连功能。连接断开后,适配器就“僵死”了,不再接收消息。

解决方案:配置自动重连与连接监听。

Spring Integration MQTT 模块提供了 MqttPahoClientFactory 的子类 DefaultMqttPahoClientFactory,我们可以通过配置其底层的 MqttClient 或使用更高级的 MqttConnectOptions 属性来实现。

@Bean
public MqttPahoClientFactory mqttClientFactory() {
    DefaultMqttPahoClientFactory factory = new DefaultMqttPahoClientFactory();
    MqttConnectOptions options = new MqttConnectOptions();
    // ... 基础配置

    // 关键:配置自动重连
    options.setAutomaticReconnect(true); // 启用自动重连
    options.setMaxReconnectDelay(30000); // 最大重连延迟(毫秒)
    options.setConnectionTimeout(15); // 连接超时(秒)

    // 设置遗嘱消息(Last Will),让Broker在客户端异常断开时通知其他客户端
    options.setWill("system/status", "{\"status\":\"offline\"}".getBytes(), 1, true);

    factory.setConnectionOptions(options);

    // 可选:配置线程池,处理连接事件
    factory.setExecutor(Executors.newFixedThreadPool(2));
    return factory;
}

对于入站适配器,还需要确保在连接恢复后重新订阅主题。MqttPahoMessageDrivenChannelAdapter 在自动重连启用时通常会处理这一点,但为了保险,可以添加一个 ConnectionListener。

@Bean
public MessageProducer inbound(MqttPahoClientFactory factory) {
    String clientId = generateUniqueClientId() + "-consumer";
    MqttPahoMessageDrivenChannelAdapter adapter =
            new MqttPahoMessageDrivenChannelAdapter(clientId, factory, "device/#", "alert/#");

    adapter.setCompletionTimeout(5000);
    adapter.setConverter(new DefaultPahoMessageConverter());
    adapter.setQos(1);
    adapter.setOutputChannel(mqttInputChannel());

    // 添加连接状态监听
    adapter.addConnectionListener(new MqttConnectionListener() {
        @Override
        public void connectionLost(Throwable cause) {
            log.error("MQTT 连接丢失: {}", cause.getMessage());
        }

        @Override
        public void connectComplete(boolean reconnect, String serverURI) {
            log.info("MQTT 连接成功,是否为重连: {}, 服务器: {}", reconnect, serverURI);
            if (reconnect) {
                // 重连后可以执行一些恢复逻辑,比如重新发布状态
                log.info("连接已恢复,重新订阅主题...");
            }
        }
    });

    return adapter;
}

2. QoS 级别的误解与错误配置:从“丢消息”到“消息风暴”

服务质量(Quality of Service)是 MQTT 的核心特性,但也是误解最多的部分。很多开发者只是机械地设置为 1 或 2,却不清楚其背后的行为和对系统的影响。

第三个深坑:QoS 1/2 在 Spring Integration 中的异步处理与消息积压。 当你使用 MqttPahoMessageHandler 发送 QoS 1 的消息时,它默认是异步的(setAsync(true))。这意味着 sendMessage 方法会立即返回,而消息的确认(PUBACK)在后台处理。如果网络不稳定或 Broker 响应慢,大量未确认的消息会积压在客户端的内部队列中。默认队列大小是有限的,一旦写满,新的发送调用可能会阻塞或抛出异常。

解决方案:理解并管理发送流控。

首先,你需要监控发送状态。可以为 MqttPahoMessageHandler 设置一个 MqttCallback 来监听发送成功或失败的回调。

@Component
@Slf4j
public class MqttProducer {
    // ... 注入 factory 和 config

    private MqttPahoMessageHandler createMessageHandler() {
        String producerClientId = mqttConfig.getClientIdPrefix() + "-producer-" + UUID.randomUUID().toString().substring(0, 8);
        MqttPahoMessageHandler handler = new MqttPahoMessageHandler(producerClientId, mqttClientFactory);

        handler.setAsync(true);
        handler.setAsyncEvents(true); // 启用异步事件,以便接收发送确认

        // 设置回调
        handler.setCallback(new MqttCallback() {
            @Override
            public void connectionLost(Throwable cause) {
                log.error("生产者连接丢失", cause);
            }

            @Override
            public void messageArrived(String topic, MqttMessage message) {
                // 生产者通常不处理接收消息
            }

            @Override
            public void deliveryComplete(IMqttDeliveryToken token) {
                // 消息送达(对于QoS 0是立即,对于QoS 1/2是收到确认后)时触发
                if (token.getException() != null) {
                    log.warn("消息发送失败,主题: {}", token.getTopics()[0], token.getException());
                } else {
                    log.debug("消息发送确认,主题: {}", token.getTopics()[0]);
                }
            }
        });

        handler.afterPropertiesSet();
        return handler;
    }

    // 考虑使用单例或池化的 Handler,避免每次发送都创建
    private final MqttPahoMessageHandler cachedHandler = createMessageHandler();

    public void sendMessage(String topic, String payload, int qos, boolean retained) throws MqttException {
        // ... 构建消息
        try {
            cachedHandler.handleMessage(message);
        } catch (MessageHandlingException e) {
            // 捕获处理异常,可能包含MqttException
            Throwable cause = e.getCause();
            if (cause instanceof MqttException) {
                throw (MqttException) cause;
            }
            throw new MqttException(e);
        }
    }
}

其次,对于高吞吐量场景,需要调整客户端的内存和队列设置。这通常需要在创建 MqttClient 实例时传入 MqttClientPersistence 参数,但在 Spring Integration 的封装下,配置起来有点麻烦。一个更实用的方法是根据业务重要性区分 QoS。

消息类型推荐 QoS理由配置示例
实时传感器数据(高频,可容忍丢失)0性能优先,避免确认开销sendMessage(topic, data, 0, false)
设备控制命令(关键指令)2确保恰好一次送达,避免重复执行sendMessage(topic, command, 2, false)
系统状态更新(需留存)1 或 2,并设置 retained=true新订阅者能获取最新状态sendMessage(topic, status, 1, true)
业务告警/通知1至少一次,平衡可靠性与性能sendMessage(topic, alert, 1, false)

第四个深坑:消费者端的 QoS 不匹配与消息重复处理。 你可能会在发送端使用 QoS 1,但在订阅端(MqttPahoMessageDrivenChannelAdapter)的 setQos 方法中设置了不同的值。订阅时的 QoS 表示客户端希望从服务器接收消息的最大质量等级,它会被 Broker 和发布者的 QoS 共同决定最终传递等级。 如果订阅 QoS 低于发布 QoS,可能导致消息降级传递。更严重的是,在 QoS 1 下,如果客户端处理消息后没有正确响应,Broker 可能会重传,导致你的 @ServiceActivator 方法被重复调用。

解决方案:确保端到端语义一致,并实现消费幂等性。

  1. 统一配置:在配置类中定义一个默认 QoS,并在生产者和消费者中显式使用它,避免硬编码数字散落在代码各处。

    // 在 MqttConfig 中
    @Data
    public class MqttConfig {
        private int defaultPublishQos = 1;
        private int defaultSubscribeQos = 1;
        // ...
    }
    
  2. 实现幂等消费:这是处理消息中间件中“至少一次”或“恰好一次”语义的黄金法则。在消费者方法中,根据消息ID或业务键进行去重判断。

    @Component
    @Slf4j
    public class MqttConsumer {
        // 简单的内存去重缓存,生产环境可用Redis
        private final Cache<String, Boolean> processedMessageCache = 
                CacheBuilder.newBuilder().expireAfterWrite(10, TimeUnit.MINUTES).build();
    
        @ServiceActivator(inputChannel = "mqttInputChannel")
        public void handleMessage(byte[] payload,
                                 @Header(MqttHeaders.RECEIVED_TOPIC) String topic,
                                 @Header(MqttHeaders.RECEIVED_QOS) int qos,
                                 @Header(MqttHeaders.RECEIVED_MESSAGE_ID) int messageId,
                                 @Header(MqttHeaders.ID) String uuidHeader) { // Spring Integration 生成的消息UUID
    
            String messageKey = topic + ":" + messageId; // 或使用业务唯一标识
            synchronized (this) { // 简单同步,高并发需用分布式锁
                if (processedMessageCache.getIfPresent(messageKey) != null) {
                    log.warn("检测到重复消息,已跳过处理。主题: {}, 消息ID: {}", topic, messageId);
                    return; // 重复消息,直接返回
                }
                processedMessageCache.put(messageKey, true);
            }
    
            // 真正的业务处理逻辑
            processMessage(topic, new String(payload, StandardCharsets.UTF_8));
        }
    }
    

3. 主题设计与通配符订阅的陷阱

MQTT 的主题(Topic)是字符串,用斜杠 / 分隔层级。通配符 +(单层)和 #(多层)非常强大,但也容易误用。

第五个深坑:滥用通配符 # 导致的意外订阅与消息洪泛。 为了省事,你可能会让一个消费者订阅 “sensor/#” 来接收所有传感器数据。但如果某个设备错误地或恶意地发布了主题为 “sensor/device-123/very/deep/nested/data” 的消息,你的消费者也会照单全收。这不仅增加了不必要的网络流量和处理负载,还可能引发安全或逻辑问题。

解决方案:遵循最小权限原则,设计清晰的主题结构,并在服务端进行校验。

  1. 精细化订阅:尽量订阅具体的主题路径,而不是一味使用 #。

    // 不推荐
    adapter.addTopic("sensor/#", 1);
    // 推荐
    adapter.addTopic("sensor/+/temperature", 1);
    adapter.addTopic("sensor/+/humidity", 1);
    adapter.addTopic("sensor/+/status", 1);
    

    如果主题模式确实复杂,可以考虑使用多个适配器或动态订阅。

  2. 设计规范的主题命名空间:在项目初期就制定并遵守主题约定。例如:

    {租户}/{项目}/{设备类型}/{设备ID}/{数据流}/{属性}
    tenant-a/project-x/thermometer/device-001/reading/temperature
    tenant-a/project-x/thermometer/device-001/reading/humidity
    tenant-a/project-x/thermometer/device-001/control/mode
    

    这样的结构清晰,便于按不同维度进行订阅和管理。

  3. 在 Broker 端实施访问控制列表(ACL):这是最根本的解决方案。像 EMQX、Mosquitto 这样的 Broker 都支持 ACL,可以严格限制每个客户端只能发布或订阅特定的主题模式,从源头上杜绝越权访问。

4. 消息序列化、负载与性能考量

当消息内容从简单的字符串变为复杂的 JSON 或二进制数据时,序列化方式和处理不当会成为性能瓶颈和 Bug 之源。

常见问题:字符串与字节数组的转换混乱。 在消费者中,你收到的 payload 可能是 byte[],也可能是已经被转换的 String,这取决于 DefaultPahoMessageConverter 的 setPayloadAsBytes 设置。如果设置不一致,会导致 ClassCastException。

解决方案:统一序列化协议,并优化大消息处理。

  1. 明确转换器配置:在入站和出站配置中,明确指定 payload 的类型。通常,设置为 false 让框架帮你转换成 String 更方便。

    // 在 MqttInboundConfig 中
    DefaultPahoMessageConverter converter = new DefaultPahoMessageConverter();
    converter.setPayloadAsBytes(false); // 消费端,转换为String
    adapter.setConverter(converter);
    
    // 在生产者发送时,框架会自动将String转换为byte[]
    Message<String> message = new GenericMessage<>(payload, headers);
    
  2. 对于复杂对象,使用 JSON:在服务层统一使用如 Jackson 库进行序列化和反序列化。

    @Service
    public class DeviceMessageService {
        private final ObjectMapper objectMapper = new ObjectMapper();
    
        public void sendDeviceData(DeviceData data) throws MqttException, JsonProcessingException {
            String topic = String.format("device/%s/data", data.getDeviceId());
            String payload = objectMapper.writeValueAsString(data);
            mqttProducer.sendMessage(topic, payload, 1, false);
        }
    
        @ServiceActivator(inputChannel = "deviceDataChannel")
        public void handleDeviceData(String payload) throws JsonProcessingException {
            DeviceData data = objectMapper.readValue(payload, DeviceData.class);
            // ... 处理业务
        }
    }
    
  3. 警惕大消息:MQTT 协议设计用于小载荷通信。单个消息过大(例如超过 256KB)可能导致 Broker 或客户端内存压力增大、网络传输延迟。对于大文件或图片,应该:

    • 使用分片传输。
    • 或者,更常见的做法是,通过 MQTT 发送一个包含文件存储地址(如 S3 对象键)的元数据消息,接收方再通过其他方式(如 HTTP)去拉取文件。

5. 测试策略:从单元测试到集成测试的鸿沟

基于 @MockBean 的单元测试可以验证你的服务逻辑是否按预期调用了 MqttProducer,但它完全绕过了真实的 MQTT 连接、网络和 Broker。很多连接、QoS、重连相关的问题在单元测试中根本无法暴露。

解决方案:建立分层的测试策略。

  1. 单元测试(Unit Test):继续使用 Mock 来测试业务逻辑的正确性,如你原始代码中的 MqttTests。

  2. 集成测试(Integration Test):这是发现 MQTT 集成问题的关键。你需要一个真实的、隔离的 MQTT Broker 进行测试。

    • 使用嵌入式 Broker:在测试环境中启动一个像 Moquette 这样的嵌入式 MQTT Broker。
    @SpringBootTest
    @TestPropertySource(properties = {
        "mqtt.host-url=tcp://localhost:1883" // 指向嵌入式Broker
    })
    @DirtiesContext // 确保上下文在测试后清理
    public class MqttIntegrationTest {
        @Autowired
        private MqttService mqttService;
        @Autowired
        private MqttConsumer mqttConsumer;
    
        private static EmbeddedMoquetteBroker broker;
    
        @BeforeAll
        static void startBroker() throws Exception {
            broker = new EmbeddedMoquetteBroker();
            broker.start();
        }
    
        @AfterAll
        static void stopBroker() {
            broker.stop();
        }
    
        @Test
        public void testMessageSendAndReceive() throws Exception {
            // 使用 CountDownLatch 或 Mockito 的 ArgumentCaptor 来验证消费者是否收到了消息
            CountDownLatch latch = new CountDownLatch(1);
            // ... 模拟消费者接收到消息后 latch.countDown()
            mqttService.sendDeviceStatus("test-device", "online");
            assertTrue(latch.await(5, TimeUnit.SECONDS)); // 等待消息被消费
        }
    }
    
    • 测试边界情况:在集成测试中模拟网络中断(如通过代理工具断开连接)、Broker 重启,观察客户端的重连和消息恢复行为。
  3. 契约测试(可选):如果你的服务需要与其他使用 MQTT 的微服务交互,可以考虑定义主题和消息格式的契约,并使用 Pact 等工具进行测试,确保双方对接口的理解一致。

避开这五个深坑,你的 Spring Boot 3 MQTT 集成方案就从“实验室可运行”向“生产环境可用”迈进了一大步。记住,分布式消息通信没有银弹,持续监控客户端的连接状态、消息吞吐量、错误日志,并根据实际运行情况调整参数(如心跳间隔、重试次数、队列大小),才是保证系统长期稳定的不二法门。在我最近负责的一个物联网项目中,正是将客户端的动态生成和重连策略优化后,才将线上连接稳定性从 95% 提升到了 99.9% 以上。

SpringBoot整合MQTT总结 目录 前言: 一、什么是mqtt 二、主要思想 发布/订阅模式 三、MQTT重要概念 3.1 MQTT Client 3.2 MQTT Broker 3.3 MQTT Connection 3.4 MQTT主要参数 四、软件和Apollo 4.1 安装Apollo 4.2安装Postman 4.3 安装MQTTBox 五、代码实现 5.1 配置pom.xml 5.2 配置MQTT服务器基本信息 5.3 配置读取yml文件的类MqttConfiguration 5.4... 阅读详情

相关推荐

【MQTT】【实战】---- Spring boot3 整合MQTT详细教程

基于spring boot3 + lombok 1.18.30 + mybatis plus 3.5.5 +jdk17 + nacos3 ,

记录生活 1267

springboot3集成MQTT 发送信息和接收信息

也是一个定义好的 Spring Boot 配置类,用于设置和管理 MQTT 客户端的发送功能,它定义了如何创建 MQTT 客户端连接、配置连接参数,并将消息发送到指定的 MQTT 主题,建立一个mqttOutBoundChannelIOT 的消息通道,用于发送消息到mqtt主题。2、在application.yml中配置好相关属性,便与后续连接地址或者是账号密码发生变化,不需要去改代码直接修改配置文件即可,由于我这边使用的是购买的mqtt服务,不是自己本地配置mqtt服务所以连接地址不一定一个模样。

PerfectOpening的博客 1779

Spring boot整合MQTT做消息队列

前言

dupengcheng1的博客 8137

使用Springboot实现MQTT通信

MQTT(Message Queuing Telemetry Transport)是一种基于发布/订阅模型的轻量级消息传输协议,常用于物联网(IoT)场景中。它设计简洁、带宽占用少,非常适合资源受限的设备和网络环境。 一、MQ协议 MQTT 特点 轻量级协议: 设计简单,占用带宽少,特别适合嵌入式设备和不稳定的网络环境。 发布/订阅模型: 客户端通过主题(Topic)发布消息,订阅者通过主题接收消息,彼此不直接通信。 可靠性保障: 提供三种服务质量(QoS)等级,确

baoshanzhongxue的博客 4399

【MQTT】【实战】---- Spring Boot3 实现MQTT消息队列的完整解决方案

本文提供了Spring Boot 3整合MQTT消息队列的完整实战解决方案。详细介绍了从项目初始化、核心依赖配置,到构建连接工厂、实现消息生产者与消费者的全流程,并深入探讨了QoS、主题规划等生产环境部署的最佳实践,帮助开发者快速构建高可靠的物联网或设备通信系统。

weixin_28419039的博客 439

Spring Boot 3整合MQTT完整Demo:连接、订阅、发布与联调实战

MQTT是一种基于发布/订阅模型的轻量级消息传输协议,运行于TCP之上,专为网络不稳定、带宽受限、设备资源有限的物联网环境而设计。理解其Broker、Topic、客户端等核心概念,是搭建可靠消息链路的基础。在Spring Boot工程中集成MQTT客户端,能够实现服务与设备之间的异步解耦,广泛应用于设备状态上报、命令下发、系统间通知等场景。本文基于Spring Boot 3.x与Eclipse Paho客户端库,结合EMQX Broker,整理了一套完整的集成Demo,涵盖环境搭建、连接配置、订阅回调、消息

weixin_34320159的博客 361

【spring boot】---- spring boot 3 整合 Mqtt 客户端

本文介绍了如何在Spring Boot项目中集成MQTT功能。首先添加必要的依赖项,包括spring-integration-mqtt和spring-boot-starter-integration。然后配置MQTT连接参数,如服务器地址、用户名密码等。核心实现包括:1)MqttConfig配置类,设置客户端工厂和消息通道;2)MqttMessageService提供消息发送功能;3)MqttMessageHandler处理接收消息;4)MqttController提供REST接口。使用时需确保MQTT服务

记录生活 465

Spring Boot 整合 MQTT 完整指南:从 Paho 配置到断线重连最佳实践

在物联网后端开发中,消息通信的可靠性与实时性往往决定系统整体质量,而 MQTT 协议凭借轻量级、低带宽和发布/订阅模型,成为设备接入的首选方案。理解 MQTT 的核心机制——如 Clean Session 控制会话恢复状态、Keep Alive 维持连接活跃、QoS 等级平衡消息可靠性与性能——是构建稳健通信链路的基础。Spring Boot 作为主流微服务框架,通过 Eclipse Paho 客户端可实现对 MQTT 的高效集成,将连接生命周期纳入容器管理,并通过分层设计隔离消息收发与业务逻辑。在工程实践

weixin_34174105的博客 391

Springboot实现MQTT通信

MQTT协议是轻量、简单、开放和用范围非常广泛。在很多情况下,包括受限的环境中,如:机器与机器(M2M)通信和物联网(IoT)。发布和订阅① QoS 0 至多一次这一级别会发生消息丢失或重复,消息发布依赖于底层TCP/IP网络。即:

一休求索 2万+

Spring Boot整合MQTT实现物联网设备消息通信实战

消息通信是物联网与分布式系统的基础组件。在设备数据采集、指令下发、即时通信等场景中,如何让海量设备与后端服务可靠、松耦合地交互是工程核心挑战。MQTT作为一种轻量级发布/订阅消息协议,凭借低带宽占用、QoS分级和离线消息保留等特性,成为物联网接入的事实标准。本文从概念原理出发,解析MQTT的Broker、Topic与QoS机制,并结合Spring Boot生态,展示基于Eclipse Paho客户端的完整整合方案。涵盖连接配置、消息监听、订阅发布、保留消息与多实例部署等关键环节,并通过实测与踩坑经验,帮助开

weixin_33836874的博客 348

AI Pika 生成进击的巨人动漫分镜案例

AI Pika 生成进击的巨人动漫分镜案例 Pika 是一个使用AI生成和编辑视频的平台。

独立开发,substack顶级编辑 2575

Spring Boot + Spring Integration整合MQTT打造双向通信客户端

本文分两个章节讲解MQTT相关的知识,第一部份主要讲解MQTT的原理和相关配置,第二个章节主要讲和Spring boot的integration相结合代码的具体实现,如果想快速实现功能,可直接跳过第一章节查看第二章讲。

weixin_71894495的博客 4198

无线自组织网络基础知识

参考书籍:《无线自组织网络路由协议及应用》 目录第一章 绪论1.1 无线自组织网络概述1.1.1 无线自组织网络的定义及分类1.1.2无线自组织网络的主要特点1.1.3无线自组织网络的应用与发展1.无线自组织网络的应用2.无线自组织网络的起源和发展1.2典型的无线自组织网络1.2.1移动Ad Hoc网络1、移动Ad Hoc网络的定义2.移动AdHoc网络的特点3.移动Ad Hoc网络的应用1.2....

逸凌Time 2万+

MQTT:从核心概念到Spring Boot整合实战

MQTT是一种基于"发布订阅模式"的轻量级的消息传输协议!,是一种传统的客户端-服务器架构的替代方案,因为一般传统的客户端-服务器是客户端能够直接和服务器进行通信完成消息的传输。发布订阅模式会将发送消息的发布者publisher与接收消息的订阅者subscribers进行分离,publisher与subscribers 并不会直接通信,他们甚至都不清楚对方是否存在,他们之间的交流由第三方组件broker代理。报文是网络中交换与传输的数据最小单元,通俗来讲就是站点一次性要发送的数据块。

小金的博客 1660

手把手教你解决CentOS sshd启动报错:从权限问题到目录缺失的全套解决方案

本文提供了一套完整的CentOS SSH服务启动故障排查与修复方案。针对sshd启动报错,从systemd日志分析、sshd -t配置测试入手,详细解决了私钥文件权限过宽(如0644错误)和权限分离目录缺失等典型问题,并附带了扩展排查清单,帮助运维人员系统性地定位和解决连接故障。

weixin_29248611的博客 154

利用Arcgis提取nc数据并计算区域年均温

1.下载数据。2.解压数据至不含中文的路径中。打开工具箱中的多维分析工具-创建NetCDF栅格图层,导入数据。3.打开工具箱中的数据管理工具-图层和表视图-创建栅格图层,导入数据,对输出数据进行命名,得到月均温栅格数据。4.选择工具箱-Spatial Analyst工具(空间分析工具)-地图代数-栅格计算器,计算全国一年年均温。​5.将其导出为.tif格式数据,方便后期使用。6.选择工具箱-Spatial Analyst工具(空间分析工具)-区域分析--以表格显示分区统计,得到分区域的气温数据。

什么都学亿点点的博客 7993

SpringBoot整合EMQX(MQTT协议)

MQTT 全称为 Message Queuing Telemetry Transport(消息队列遥测传输),是一种基于 发布/订阅 模式的 轻量级物联网消息传输协议。

SherlockerSun的博客 2万+

第1部分 基础算法(提高篇)--第2章 二分与三分1439:【SCOI2010】传送带

1439:【SCOI2010】传送带 时间限制: 2000 ms 内存限制: 65536 KB 提交数: 372 通过数: 212 【题目描述】 在一个2维平面上有两条传送带,每一条传送带可以看成是一条线段。两条传送带分别为线段AB和线段CD。lxhgww在AB上的移动速度为P,在CD上的移动速度为Q,在平面上的移动速度R。现在lxhgww想从A点走到D点,他想知道最少需要走多长时间。 【输入】 输入数据第一行是4个整数,表示A和B的坐标,分别为Ax,Ay,Bx,By 第二行是4个整

zqhf123的博客 839

Spring Boot 整合 MQTT 发布/订阅消息

Spring Boot 整合 MQTT 发布/订阅消息

m0_51985332的博客 2137

一文学会Cadence Sigrity PDN仿真——硬件新手小白都能看懂的保姆级教程

电源完整性的仿真,实际上是在仿真以及优化系统中的等效串联电阻。知道了仿真以及优化的目标之后,接下来就是要弄明白这个串联电阻从哪儿来以及怎么优化。整个系统中的串联电阻实际上由三部分组成:没有相位的阻抗,有相位的容抗和感抗,得益于相位,在某个特定的频点,容抗和感抗会大小相等,相位相反而相互抵消,这时候整个系统中就剩下了阻抗,所以整个系统的串联电阻达到了一个最低值,这种现象就是----谐振。当系统处于谐振点时候,整个系统会有一个最小的串联电阻,所以第一个优化电阻的手段就是让谐振来的更频繁一点。

学习帮的博客 2万+

用友U8库龄分析避坑指南:物料出入库日期计算的5个常见错误

本文深入剖析了在用友U8系统中进行库龄分析时,物料出入库日期计算的五个常见陷阱。从数据源选择、业务类型过滤、计价方式逻辑、期初数据处理到查询性能优化,逐一解析错误根源并提供避坑指南,帮助企业获得准确的库龄数据,有效管理库存与资金风险。

weixin_29209801的博客 456

Spring Boot整合MQTT

MQTT是基于代理的轻量级的消息发布订阅传输协议。

GM_115的博客 881

Unity WebGL发布避坑指南:从内存设置到字体打包,一次搞定所有常见问题

本文详细解析Unity WebGL发布的完整流程,从内存设置到字体打包,提供全面的避坑指南。涵盖关键检查清单、内存与性能优化配置、资源处理专项优化及平台适配技巧,帮助开发者高效解决常见问题,确保项目顺利发布。

weixin_28693309的博客 148

MQTT入门:在Spring Boot中建立连接及测试

通过以上步骤,我们成功地在Spring Boot项目中集成了MQTT客户端,并通过JUnit进行了简单的连接测试。

Takumilove的博客 2288

IMSL CNL 7.0.0 (x86-64)Crack

IMSL CNL 7.0.0 (x86-64)Crack intel的算法库破解文件,这是C++版本的破解文件

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

上一篇: VS2019如何兼容旧版C++项目?手把手教你安装VC6~VS2017工具集
下一篇: Android车载系统Launcher开发避坑指南:从权限申请到Activity嵌入(附CarLauncher源码分析)
Python
博客等级 码龄26年 1973粉丝 1567原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值