运维告诉我CPU飙升300%,为什么我的程序上线就奔溃了
线上服务CPU飙升的一次经历
前言
- 功能开发完成仅仅是项目周期中的第一步,一个完美的项目是在运行期体现的
- 今天我们就来看看笔者之前遇到的一个问题CPU飙升的问题。 代码层面从功能上看没有任何问题但是投入使用后却让我头大
问题描述
系统上点击数据录入功能在全局监控中会受到相关消息的通知。此时服务器CPU飙升300%
问题定位
- 首先我们先梳理下
Websocket
的数据发送的简单原理示意图。往往定位问题得清楚我们的逻辑是什么 - 当一个客户端启动时除了和
Websocket
建立连接之外,我们还需要向Websocket
服务注册当前客户端需要哪些接口的实时数据 - 我在代码内部是通过一个Map来存储这些接口签名信息的。然后客户注册时候将这些接口和客户端绑定在一起
- 当我们监听程序坚挺到数据变动就会对绑定到相关接口的客户端发送最新数据
业务定位
- 业务上很好定位,问题就是出现在我们的监听程序中。当监听到数据给
websocket
客户端发送订阅的最新变动接口时就会出现CPU飙升。持续时间还很长,稍等一会就会降下来 - 这很明显是我们推送消息的时候出现了问题
隔离业务看本质
- 作为一个合格的程序员呢,必须摆脱业务才能有所收获 。业务是我们代码的外壳所有的问题基本上都是我们本质的问题。我们线上使用用户1W内。在这种的并发场景下应该是不会出问题的。现在出了问题肯定我们的程序逻辑有缺陷
- 上面是我们的发送消息的代码。代码也很简单。先获取所有符合发送条件的客户端 。然后通过客户端内部提供的
sendMessage
方法进行推送。 - 但是这个时候的
message
是我们的接口信息。在内部会基于客户端保存的方法签名进行反射调用从而获取最新数据。在推送给客户端的 - 在上面的代码中核心的是
WebsocketManager.messageParse
。这段是获取消息然后发送。里面获取消息是基于resultful格式解析的
- 这个方法内部我们有内置了我们的四种解析方式。这里我们只需要关心
RequestMappingMessageParseHandlerImpl
这个协议。
- 关于我们内部的协议这里也不需要太在意。这是我们自己的一个设计。根据上面的图示我们也能看的出来里面
RequestMappingMessageParseHandlerImpl
是核心
产生原因
- 上面我们简单的梳理了下代码的逻辑。
- 仔细分析下我们是遍历所有客户端然后在反射调用接口数据进行返回的。实际上在消息推送时我们没必要在每个客户端内部调用数据。我们完全可以先调用数据然后在遍历客户端进行发送。
- 这也是导致CPU过高的问题。我们1W个用户同事在线的可能有5000+ 。 那么我们需要5000次以上的反射着肯定是吃不消的。这也是为什么本文开头说功能正常不代表业务正常。
解决方案
- 这就是量变引起质变。在多客户的情况下我们的设计弊端就暴露出来。这里也是笔者自己给自己挖坑。既然找到问题我们就好解决了。下面我们对代码做了一下改动
我将数据缓存起来。因为在同一批次推送时本来也应该保证数据一致性。而且我们系统对数据实时性也是可以接受一定时间延迟的。我在这里又加上缓存这样就解决了我们循环的问题
经过测试本次改动在CPU上大概优化了100倍。
总结
- 功能开发完成仅仅代表功能的实验没有问题
- 单用户和多用户完全是两种不同的用户形态。我们功能设计初期就应该尽量考虑数据量的问题
- 唯一做的好的地方是我通过责任链模式将数据解析隔离出来。否则这样的问题定位将会更加麻烦
作者: zxhtom
链接:https://juejin.cn/post/6960795554406367269
来源:juejin
有时候一个小小的问题就会引起很大的波动现象,那么处理起来也是非常的痛楚,只有找到合适的方法,这次笔者自己给自己挖坑,在这里做了一下记录。特别是在高并发到的时候,小问题会带来更大的麻烦。
技术github学习地址:https://github.com/codeGoogler/JavaCodeHub
程序员编程书籍:https://github.com/codeGoogler/ProgramBooks
关于如何学习Java,一方面需要不断的去学习,把基础知识学扎实,另一方面也要认识到java的学习不能仅仅靠理论,更多的是靠实操,所以要多练习多做项目,在实践中学习才是最好的学习方法。很多人刚开始不知道怎么去学习,这里我将一些重要的技术文章整理到了github上开源项目上,希望能给大家带来一些帮助,项目是:JavaCodeHub
另外,还整理了一些针对于程序员的编程书籍项目,都放到了github上面,项目为:ProgramBooks 需要的话可以自取。地址:https://github.com/codeGoogler/ProgramBooks
如果github访问太慢?我同时也把去放到了码云上面ProgramBooks
最后,照旧安利一波我们的公号:「终端研发部」,目前每天都会推荐一篇优质的技术相关的文章,主要分享java相关的技术与面试技巧,我们的目标是: 知道是什么,为什么,打好基础,做好每一点!这个主创技术公众号超级值得大家关注。
运维告诉我CPU飙升300%,为什么我的程序上线就奔溃了相关推荐
- 我的一个学生在运维工作中写的自动日志清理脚本程序
本文是我的一个学生在运维工作中写的自动日志清理脚本程序,我这里不评价该shell脚本写的好与坏,只是发出来,和大家做一个分享,如果能给大家带来一点点思路上的参考就够了. 自动日志清理脚本程序 #!/b ...
- Ceph运维告诉你分布式存储的那些“坑”
转载自:https://dbaplus.cn/news-134-2079-1.html 作者介绍 汪涉洋,来自美国视频网站hulu的工程师,毕业于北京理工大学计算机专业,目前从事大数据基础架构方面的工 ...
- 运维入门之CPU平均负载及问题排查
1. 小声BIBI 曾几何时,年少无知的我将CPU使用率和负载混为一谈,简单的认为负载高了就是CPU使用率高,直到碰到了一次现网事故时发现CPU的load很高,但是CPU使用率却很低,苦于基础能力薄弱 ...
- 运维不是修电脑!月薪30K的高级运维告诉你,学会这些就能逆袭
提起数据运维,大部分人的第一印象都是: 运维=修电脑+接网线+连监控+打扫机房卫生+背锅 其实这都是圈外人对运维的刻板印象,无论你是个刚入职没几个月的行业新人,还是在行业里摸爬打滚了好几年的" ...
- 【HTTPS运维神器】终于等到你!MySSL企业版重磅上线!
2019独角兽企业重金招聘Python工程师标准>>> 小王是国内某大型网站的运维管理人员,最近他向我们销售工程师吐槽了部署HTTPS网站后遇到的尴尬事: "每天高频的巡检 ...
- 【运维心得】wps云文档被其他程序锁定了怎么办?
文章目录 问题描述 解决方案 A方案 B方案 问题描述 为了支持国货,一直使用wps处理文档.这个问题,估计经常处理文字和表格的朋友都碰到过. 现象就是:当wps非正常退出以后,没有正常关闭的云文档, ...
- 写运维实习生第五周实习周报,包括心得体会和下周计划,多于300字
这周我主要学习了Linux操作系统的基础知识,包括如何使用命令行.文件系统的目录结构.进程管理.用户权限等.在学习的过程中,我逐渐感受到了Linux的强大和灵活性,并且也开始能够熟练地使用命令行进行日 ...
- 基于 Bitbucket Pipeline + Amazon S3 的自动化运维体系
1 前言介绍 随着自动化运维水平的提高,一个基础的运维人员维护成百上千台节点已经不是太难的事情,当然,这需要依靠于稳定.高效的自动化运维体系.本篇文章即是阐述如何利用 bitbucket pipeli ...
- Linux 系统日常运维九大技能和运维网络知识总结
一.Linux 系统日常运维九大技能 1.安装部署 方式:U盘,光盘和网络安装 其中网络安装已经成为了目前批量部署的首选方式:主要工具有Cobbler和PXE+kickstart 可以参考如下链接内容 ...
最新文章
- 关于JVM,你需要掌握这些!!
- Flutter 在铭师堂的实践
- Centos更换阿里云源
- 和老公去出吃饭,每次我出钱。这样正常吗?
- using + .net 中的别名
- 万稞pw80线切割编程软件_SODICK 沙迪克慢走丝线切割 T 代码在程序NC 中的小应用...
- mysql concat字符串拼接函数使用
- 金蝶K3销售价格控制模块探讨
- Python字符串转义符大全
- excel条件格式标记一整行
- python项目实战:免费下载kugou任意付费音乐
- Nginx负载均衡状态值max_fails和fail_timeout
- 为什么在wps中调整了0.5倍行距,某一页的行数不会发生变化?
- wordpress实现全站HTTPS
- 「会员卡管理系统」 · Java Swing + MySQL JDBC开发
- Spine 实用技巧大全
- mapbox中文地图_使用 Mapbox 地图
- python利用pyinstaller打包文件
- 上海常英计算机技术有限公司,工科男博士恋上理科女博士 脚踏单车千里求婚...
- Linux下的Backlight子系统(一)