ActiveMQ之Mqtt的TCP丢包

现象

Mqtt Consumer应该收到的消息少于预期,登录ActiveMQ的管理页面里的Topics,查看Messages Enqueued发现同样少于理应接收的数量。

定位问题

  1. 怀疑是TCP丢包,通过netstat -s命令观察发送消息前后Tcp信息的输出
  2. 对比两次Tcp信息的输出,发现packets pruned from receive queue because of socket buffer overrunpackets collapsed in receive queue due to low socket buffer等含有prunedcollapsed字样的数值在增多。

解决方案

  • 首先调整系统级tcp的缓冲区,修改/etc/sysctl.conf如下
net.core.rmem_max = 8388608
net.core.wmem_max = 8388608
net.core.rmem_default = 655360
net.core.wmem_default = 655360
net.ipv4.tcp_rmem = 4096 655360 8388608 # Tcp接收缓冲区,分别是最小、默认、最大
net.ipv4.tcp_wmem = 4096 655360 8388608 # Tcp发送缓冲区,分别是最小、默认、最大
net.ipv4.tcp_mem = 8388608 8388608 8388608
<transportConnector name="mqtt"
uri="mqtt+nio://0.0.0.0:1883?maximumConnections=1000&amp;
wireFormat.maxFrameSize=104857600&amp;transport.ioBufferSize=1048576&amp;
transport.socketBufferSize=4194304"/>
- 其中**+nio**表示启用**nio**方式的socket通信。Java里**nio**方式的socket比**bio**方式的更高效。mqtt默认采用**bio**。
- **socketBufferSize**调整缓冲区大小为4m,默认为64k,防止socket接收缓冲过小引发系统扔包
- **ioBufferSize**调整程序内部使用的缓冲区大小为1m,默认为8k,提高缓冲可以增加处理性能

代码分析

  • MQTTTransportFactory继承自TcpTransportFactory
    • org.apache.activemq.transport.tcp.TcpTransportFactory#doBind时解析URI带入的参数
  • org.apache.activemq.transport.mqtt.MQTTNIOTransportFactory#createTcpTransportServer创建TcpTransportServer
  • org.apache.activemq.transport.tcp.TcpTransportServer#doRunWithServerSocketChannel创建与客户端通信的Transport
    • 默认的socketBufferSize = 65536
    • 默认的ioBufferSize = 8192
  • Transportorg.apache.activemq.transport.TransportAcceptListener#onAccept处理
    • Transport被扔给org.apache.activemq.thread.TaskRunnerFactory线程池
    • 在线程池中创建org.apache.activemq.broker.Connection
  • Connection中的org.apache.activemq.broker.TransportConnection#start启动整个TCP的链路

Windows下定位问题的要点

好的,我可以为您简单介绍一下SpringBoot集成ActiveMQMQTT实现消息的发送和接收。 首先,您需要在SpringBoot项目中添加ActiveMQMQTT的依赖,可以在pom.xml文件中添加如下代码: ```xml <!-- ActiveMQ --> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-activemq</artifactId> </dependency> <!-- MQTT --> <dependency> <groupId>org.springframework.integration</groupId> <artifactId>spring-integration-mqtt</artifactId> <version>5.5.0</version> </dependency> ``` 接下来,您需要在application.properties中配置ActiveMQMQTT的连接信息,例如: ```properties # ActiveMQ spring.activemq.broker-url=tcp://localhost:61616 spring.activemq.user=admin spring.activemq.password=admin # MQTT spring.mqtt.username=admin spring.mqtt.password=admin spring.mqtt.url=tcp://localhost:1883 ``` 然后,您可以通过注入JmsTemplate和MqttPahoMessageHandler来实现消息的发送和接收。例如: ```java // ActiveMQ @Autowired private JmsTemplate jmsTemplate; public void sendMessage(String destination, String message) { jmsTemplate.convertAndSend(destination, message); } @JmsListener(destination = "testQueue") public void receiveMessage(String message) { System.out.println("Received message: " + message); } // MQTT @Autowired private MqttPahoMessageHandler mqttHandler; public void sendMessage(String topic, String message) { mqttHandler.setDefaultTopic(topic); mqttHandler.handleMessage(MessageBuilder.withPayload(message).build()); } @MessageEndpoint public class MqttMessageReceiver { @ServiceActivator(inputChannel = "mqttInputChannel") public void receiveMessage(String message) { System.out.println("Received message: " + message); } } ``` 以上代码中,sendMessage方法用于发送消息,receiveMessage方法用于接收消息。使用JmsTemplate可以很方便地发送和接收ActiveMQ消息,使用MqttPahoMessageHandler和MqttMessageReceiver可以很方便地发送和接收MQTT消息。 这就是SpringBoot集成ActiveMQMQTT实现消息发送和接收的基本流程,希望对您有所帮助。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值