ActiveMQ_Mqtt的TCP丢包
现象
Mqtt Consumer应该收到的消息少于预期,登录ActiveMQ的管理页面里的Topics,查看Messages Enqueued发现同样少于理应接收的数量。
定位问题
- 怀疑是TCP丢包,通过
netstat -s命令观察发送消息前后Tcp信息的输出 - 对比两次Tcp信息的输出,发现packets pruned from receive queue because of socket buffer overrun与packets collapsed in receive queue due to low socket buffer等含有pruned或collapsed字样的数值在增多。
- collapsed是指tcp包溢出缓冲区,此时内核尝试通过减少内存开销以换取接收队列里的空闲空间,策略是CPU换内存
- pruned是指内核在collapsed时的尝试后,仍未有足够空间接收包则此时直接扔包
- 解释来自于Red Hat Enterprise Linux Network Performance Tuning Guide 页码22
解决方案
- 首先调整系统级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
- 上述参数的解释参见How To: Network / TCP / UDP Tuning、Red Hat Enterprise Linux Network Performance Tuning
Guide、Linux Kernel Tuning - linux终端里输入
sysctl -p使之生效 - 接着修改ActiveMQHome/conf/activemq.xml如下
<transportConnector name="mqtt"
uri="mqtt+nio://0.0.0.0:1883?maximumConnections=1000&
wireFormat.maxFrameSize=104857600&transport.ioBufferSize=1048576&
transport.socketBufferSize=4194304"/>
- 其中**+nio**表示启用**nio**方式的socket通信。Java里**nio**方式的socket比**bio**方式的更高效。mqtt默认采用**bio**。
- **socketBufferSize**调整缓冲区大小为4m,默认为64k,防止socket接收缓冲过小引发系统扔包
- **ioBufferSize**调整程序内部使用的缓冲区大小为1m,默认为8k,提高缓冲可以增加处理性能
代码分析
MQTTTransportFactory继承自TcpTransportFactoryorg.apache.activemq.transport.tcp.TcpTransportFactory#doBind时解析URI带入的参数
org.apache.activemq.transport.mqtt.MQTTNIOTransportFactory#createTcpTransportServer创建TcpTransportServerorg.apache.activemq.transport.tcp.TcpTransportServer#doRunWithServerSocketChannel创建与客户端通信的Transport- 默认的
socketBufferSize = 65536 - 默认的
ioBufferSize = 8192
- 默认的
Transport受org.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下定位问题的要点
- windows下的
netstat -e -s等价于linux下的netstat -s - windows的socket缓冲区没有系统级限制,应用程序可以按需调整,资料来源于What is the size of a socket send buffer in Windows?、Design issues - Sending small data segments over TCP with Winsock
ActiveMQ_Mqtt的TCP丢包的更多相关文章
- 发生tcp丢包(拥堵、超时)重传
可以根据wireshark的Seq序列号和Ack序列号来进行详细分析. 可见,网络丢包(可能是网络拥堵.也有可能是骨干网上有"防火墙"故意随机丢包,因为这个服务器的IP放在国外)对 ...
- TCP通信丢包原因总结
今天在公司问老大,公司的项目底层,是使用的TCP,因为可靠,自动断线重连,在底层都实现了,但是我记得TCP也会有掉包的问题,所以这文章就诞生了——关于TCP掉包的问题,TCP是基于不可靠的网络实现可靠 ...
- tcp粘包,udp丢包
TCP是面向流的, 流, 要说明就像河水一样, 只要有水, 就会一直流向低处, 不会间断. TCP为了提高传输效率, 发送数据的时候, 并不是直接发送数据到网路, 而是先暂存到系统缓冲, 超过时间或者 ...
- 略解TCP乱序和丢包
在使用基于TCP实现的各种组件的时候,我们经常会处理数据包.这数据包说来奇怪,从来不会丢失,也不会乱序,只会产生粘包.底层的机制是如何实现的呢?进来我们就来用简洁易懂的文字描述清楚. 在TCP数据包设 ...
- day34 基于TCP和UDP的套接字方法 粘包问题 丢包问题
TCP 基于流的协议 又叫可靠性传输协议 通过三次握手 四次挥手 来保证数据传输完毕 缺点效率低 正因为是基于流的协议 所以会出现粘包问题粘包问题:原因一:是应为数据是先发送给操作系统,在操作系统中有 ...
- 一个RTSP/RTP over TCP 的丢包引起的问题
背景知识:可以查看https://www.cnblogs.com/lidabo/p/4483497.html RTSP/RTP over TCP TCP承载RTSP/RTP When you us ...
- 【转】使用TCP协议连续传输大量数据时,是否会丢包,应如何避免?
使用TCP协议连续传输大量数据时,是否会丢包,应如何避免? 比如发送文件.记得有人提过可能会发生什么堆栈溢出.怎样避免呢?是不是可以收到数据后发送确认包,收到确认包后再继续发送.或是发送方发送了一些数 ...
- tcp/udp只发不接,会丢包还是send失败?
这篇文章源于我看libevent的源码时想到的问题,对于libevent的buffer机制,如果接受端一直不取数据的话,会怎样?如果丢包,不现实,因为会导致数据丢失,如果不丢包,就会导致占用内存一直扩 ...
- TCP粘包, UDP丢包, nagle算法
一.TCP粘包 1. 什么时候考虑粘包 如果利用tcp每次发送数据,就与对方建立连接,然后双方发送完一段数据后,就关闭连接,这样就不会出现粘包问题(因为只有一种包结构,类似于http协议,UDP不会出 ...
随机推荐
- echarts学习总结
ECharts学习总结使用步骤1 引入ECharts <script src="echarts.min.js"></script>2 绘制一个简单的图表 为 ...
- JQuery中$.ajax()方法参数详解
url: 要求为String类型的参数,(默认为当前页地址)发送请求的地址. type: 要求为String类型的参数,请求方式(post或get)默认为get.注意其他http请求方法,例如put和 ...
- javaScript中的小细节-局部作用域中的var
javaScript中var是很神奇的,在局部作用域中,var a = b = c = 1;是不一样的,a为使用var声明的变量,而b和c则是全局下的,此类变量被称为隐式全局变量:var a = 1; ...
- Canvas——使用定时器模拟动态加载动画!
<!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8&quo ...
- Arcmap中加载互联网地图资源
本文转载自:http://blog.3snews.net/space.php?uid=6955280&do=blog&id=67981 前一段时间想在Arcmap中打开互联网地图中的地 ...
- CRM 2013 相关下载 / 2013-10-11
CRM 2013的安装文件,软件开发工具包(Sdk)以及实施指南,在微软官方网站已经有下载了. 具体地址如下: Name Url 发布日期 语言版本 说明 CRM Server htt ...
- iOS获取app图标和启动图片名字(AppIcon and LaunchImage's name)
在某种场景下,可能我们需要获取app的图标名称和启动图片的名称.比如说app在前台时,收到了远程通知但是通知栏是不会有通知提醒的,这时我想做个模拟通知提示,需要用到icon名称:再比如在加载某个控制器 ...
- Android面试题--事件处理
1.Handler 机制 Android 中主线程也叫 UI 线程,那么从名字上我们也知道主线程主要是用来创建.更新 UI 的,而其他耗时操作,比如网络访问,或者文件处理,多媒体处理等都需要在子线程中 ...
- 我的敏捷、需求分析、UML、软件设计电子书 - 下载(持续更新中)
我将所有我的电子书汇总在一起,方便大家下载!(持续更新) 文档保存在我的网站——软件知识原创基地上(www.umlonline.org),请放心下载. 1)软件设计是怎样炼成的?(2014-4-1 发 ...
- WEB页面中常见的四种控件的必须的测试
以下为常规的需求,除非需求有明确说明,如密码输入框中可以输入空格. 输入框 1. 为空,但页面中明确说明不能为空(带有星号或者只有这一个输入框),有以下两种情况: a. 不进行输入或者使其为空:焦 ...