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不会出 ...
随机推荐
- gitignore 规范
gitignore 应该包含 5 块内容: 当前项目需要忽略的文件 项目性质需要忽略的文件(比如是 nodejs 项目,有些文件就需要忽略) 所有项目都需要忽略的文件(比如日志.临时文件) 操作系统需 ...
- 开发属于自己的yeoman脚手架(generator-reactpackage)
自从前后端开始分离之后,前端项目工程化也显得越来越重要了,之前写过一篇搭建基于Angular+Requirejs+Grunt的前端项目教程,有兴趣的可以点这里去看 但是有些项目可以使用这种方式,但有些 ...
- javascript的defer和async的区别。
我们常用的script标签,有两个和性能.js文件下载执行相关的属性:defer和async defer的含义[摘自https://developer.mozilla.org/En/HTML/Elem ...
- Android Weekly Notes Issue #225
Android Weekly Issue #225 October 2nd, 2016 Android Weekly Issue #225 本期内容包括: Android 7.0的Quick Sett ...
- IOS开发基础知识碎片-导航
1:IOS开发基础知识--碎片1 a:NSString与NSInteger的互换 b:Objective-c中集合里面不能存放基础类型,比如int string float等,只能把它们转化成对象才可 ...
- 【代码笔记】iOS-自定义开关
一,效果图. 二,工程图. 三,代码. RootViewController.h #import <UIKit/UIKit.h> #import "ToggleView.h&qu ...
- 20-C语言结束
我回去看了下5号写的.虽然今天已经21号了~,花了16天. 复习完C专题,接下来我大概会用C做一些操作系统/信息安全的小东西,会发到博客里,敬请期待! ----2016/11/21
- Unity3D安卓出包报错
今天又遇到了在安卓出包时,直接报错了两个错误,报错信息分别如下: Installation failed with the following output: pkg: /data/local/tmp ...
- 论Pair的重要性
这些天我在用React和D3做图表,从已经实现的图表里复制了一些坐标轴的代码,发现坐标轴上的n个点里,只有第一个点下面能渲染出文字提示,其余点下面都无法渲染出文字. 和组里的FL一起百思不得其解好几天 ...
- CentOS 7 x64下Apache+MySQL(Mariadb)+PHP56的安装
每次搭建新服务器,都要来来回回把这些包再装一下,来来回回搞了不下20遍了吧,原来都是凭经验,配置过程中重复入坑是难免的,故写此文做个备忘.虽然有像xampp这样的集成包,但是在生产环境的Linux发行 ...