线上消息堆积与感想
【环境介绍】
1.应用服务器部署在阿里云
2.消息中间件使用阿里云RocketMQ
前两天线上发生了MQ消息堆积的情况,在我的知识认知里,消息堆积的原因是消费者消费能力差,无法及时消费消息,才会导致消息堆积.
那么有哪些因素会导致消费者消费能力差呢? 我目前的理解有三种情况
1.Dubbo的RPC调用时间太久
2.查询数据库或者插入数据太久
3.业务中还有其他耗时操作,比如发送邮件
记得以前看博客的时候,似乎看到过说发送邮件耗时久导致消息堆积的情况, 而现在就发生在自己身上,真是冥冥之中自有安排.
发生消息堆积,查看阿里云上的线程堆栈信息
从线程堆栈上来看,线程在发送邮件,准确说在连接. 根据代码分析以及一段时间的观察线程,断定就是发送邮件的逻辑导致的.临时注释掉这段代码,重新发布,问题解决.
其实发送邮件并不会耗时太久, 而根据阿里云ARMS上的错误显示,消息消费失败总耗时2min. 为什么发送邮件(准确说是连接)会这么久. 因为那段发送邮件的代码在本地测试,只耗时1s左右.
<dependency> <groupId>javax.mail</groupId> <artifactId>mail</artifactId> <version>1.4</version> </dependency>
import javax.mail.Authenticator; import javax.mail.BodyPart; import javax.mail.Message; import javax.mail.Message.RecipientType; import javax.mail.MessagingException; import javax.mail.Multipart; import javax.mail.PasswordAuthentication; import javax.mail.Session; import javax.mail.Transport; import javax.mail.internet.InternetAddress; import javax.mail.internet.MimeBodyPart; import javax.mail.internet.MimeMessage; import javax.mail.internet.MimeMultipart; import java.util.Date; import java.util.HashMap; import java.util.Map; import java.util.Properties; public static void main(String[] args) { long start = System.currentTimeMillis(); try { // 配置仅为了文章说明,并不是真实配置 Mail mail = new Mail("xyz@qq.com", "password"); mail.addToAddress(Mail.ReceiveType.TO, "opq@qq.com"); mail.setMailInfo(Mail.Mode.TEXT_MAIL, "这是测试数据", "这是测试数据"); mail.send(); } catch (Throwable e) { System.out.println(e.getMessage()); } long end = System.currentTimeMillis(); System.out.println(end - start); }
我把上面的代码在线上机器测试,发现耗时的确在2min. 为了描述, 我这里以我自己的阿里云服务器做演示.
测试了两次,耗时都在1min. 接下来通过strace命令查看系统调用, 看下具体耗时在哪个系统调用上.
关于如何使用strace命令查看系统调用,在我之前的文章中也有过一些介绍
邮件发送默认使用25号端口,搜索下关键字25
grep -iE 'connect.25' strace
在连接邮件服务器25号端口的时候,超时了.
为什么本地耗时1s, 而在阿里云上的机器就耗时这么久呢? 原因只要一个
阿里云默认禁用了25号端口,所以导致连接超时.
在本次事件中,还发现一个情况
消息已经消费成功,可是MQ Broker依然投递消息. 简单咨询了阿里云客服,也没给我个具体原因.
请回答
常见消费者消费慢的因素有哪些?
消费慢的时候,要查看下线程堆栈,观察线程都在干啥
你会使用strace命令查看系统调用吗?
如上图,目前给我的感觉,作为一个Java码农或者工程师,系统上应该要对以上四个都要熟悉.
你不仅要会使用Java层面的Map,Thread,AQS等等, 当它调用到native方法时候,你还要去JVM层面追踪查看具体的实现,JVM层面可是C或者C++语言. 还有它最终调用到的系统调用是哪个. 而绝大多数人都停留在Java层面,当然这个层面达到精通也很难. 了解JVM的更少了, 能够继续向下了解C和Linux的那就凤毛麟角了.
你掌握的技术,一个刚毕业的学生在2个月或者半年就掌握了,但是别人掌握的知识,你未必在1-2年能掌握. 这或许就是人与人之间的区别. 你是哪种人呢?
做技术真的挺难的...

低调大师中文资讯倾力打造互联网数据资讯、行业资源、电子商务、移动互联网、网络营销平台。
持续更新报道IT业界、互联网、市场资讯、驱动更新,是最及时权威的产业资讯及硬件资讯报道平台。
转载内容版权归作者及来源网站所有,本站原创内容转载请注明来源。
- 上一篇
这一次,彻底搞懂 Go Cond
hi,大家好,我是 haohongfan。 本篇文章会从源码角度去深入剖析下 sync.Cond。Go 日常开发中 sync.Cond 可能是我们用的较少的控制并发的手段,因为大部分场景下都被 Channel 代替了。还有就是 sync.Cond 使用确实也蛮复杂的。 比如下面这段代码: packagemainimport("fmt""time")funcmain(){done:=make(chanint,1)gofunc(){time.Sleep(5*time.Second)done<-1}()fmt.Println("waiting")<-donefmt.Println("done")} 同样可以使用 sync.Cond 来实现 packagemainimport("fmt""sync""time")funcmain(){cond:=sync.NewCond(&sync.Mutex{})varflagboolgofunc(){time.Sleep(time.Second*5)cond.L.Lock()flag=truecond.Signal()cond.L.Un...
- 下一篇
6 张图带你彻底搞懂分布式事务 XA 模式
作者 | 朱晋君 来源 | 阿里巴巴云原生公众号 XA 协议是由 X/Open 组织提出的分布式事务处理规范,主要定义了事务管理器 TM 和局部资源管理器 RM 之间的接口。目前主流的数据库,比如 oracle、DB2 都是支持 XA 协议的。 mysql 从 5.0 版本开始,innoDB 存储引擎已经支持 XA 协议,今天的源码介绍实验环境使用的是 mysql 数据库。 两阶段提交 分布式事务的两阶段提交是把整个事务提交分为 prepare 和 commit 两个阶段。以电商系统为例,分布式系统中有订单、账户和库存三个服务,如下图: 第一阶段,事务协调者向事务参与者发送 prepare 请求,事务参与者收到请求后,如果可以提交事务,回复 yes,否则回复 no。 第二阶段,如果所有事务参与者都回复了 yes,事务协调者向所有事务参与者发送 commit 请求,否则发送 rollback 请求。 两阶段提交存在三个问题: 同步阻塞,本地事务在 prepare 阶段锁定资源,如果有其他事务也要修改 xiaoming 这个账户,就必须等待前面的事务完成。这样就造成了系统性能下降。 协调节...
相关文章
文章评论
共有0条评论来说两句吧...
文章二维码
点击排行
推荐阅读
最新文章
- Springboot2将连接池hikari替换为druid,体验最强大的数据库连接池
- Docker快速安装Oracle11G,搭建oracle11g学习环境
- CentOS7设置SWAP分区,小内存服务器的救世主
- Mario游戏-低调大师作品
- Docker使用Oracle官方镜像安装(12C,18C,19C)
- 2048小游戏-低调大师作品
- Jdk安装(Linux,MacOS,Windows),包含三大操作系统的最全安装
- MySQL8.0.19开启GTID主从同步CentOS8
- CentOS8安装Docker,最新的服务器搭配容器使用
- CentOS8安装MyCat,轻松搞定数据库的读写分离、垂直分库、水平分库