从CPU100%高危故障到稳定在10%:一个月的优化之旅,成功上线!
引言
经过三个月的开发,项目通过了所有测试并上线,然而,我们发现项目的首页几乎无法打开,后台一直发生超时错误,导致CPU过度负荷。在这次项目开发过程中,我制定了一份详细的技术优化方案。考虑到客户无法提供机器硬件配置,我们只能从软件方面寻找解决方案,以满足客户的预期。同时,我还准备了一个简单的项目复盘,如果你对此感兴趣,也可以一起查看。

初期优化
在进行第一次优化时,我们发现SQL的基本书写存在问题。通过使用pinpoint工具,我们成功抓取了所有的SQL语句。然后,我们请一位对业务非常熟悉的人对所有的SQL进行了审查,主要是优化SQL书写中的基本错误。由于开发人员的疏忽,导致了数据库的全表查询,但是由于测试数据库的数据量不足,测试环境并没有发现潜在的基础SQL问题。经过第一轮SQL优化,现在所有的SQL语句已经得到了正确的修正。
经过压力测试后,我们发现数据库的CPU已经超负荷运行。为了进一步优化性能,我们决定进行SQL的详细优化。在查询表关联的过程中,我们发现有很多字段实际上已经在业务表中冗余存在,因此无需再去关联另外一张表。通过减少表的关联操作,我们可以有效提高SQL的执行效率。
中期优化
由于测试数据量不足且业务关联性较差,我们需要申请将正式数据库中涉及的表数据迁移至测试数据库,以模拟正式环境进行压力测试。
经过初步讨论,我们认为业务表的数据量很大可能导致了SQL查询的缓慢和CPU性能的占用。为了优化这个问题,我们决定根据所有报表涉及的表及其字段,扫描业务增量数据并抽离出一个小表用于报表业务查询。
在进行数据迁移的过程中,我们要注意的是,除非数据量很小的表,不要直接将其抽离到小表中。相反,我们需要引入一个中间表来提前缓冲数据。如果直接去除中间表,可能会导致对业务表的锁定,从而降低业务操作的性能。
注意点:在上线之前,务必确保准备好初始化表数据和相应的表索引。丢失一个都会导致生产数据库的CPU跑满。

后期优化
由于项目需要进行时间范围查询,当选择以月为单位时,首页在压测并发下未能达到预期要求。因此,我们进行了方案升级,引入了结果表的概念。具体而言,我们按照月份的最小统计范围提前生成结果统计表。也有人提出在此阶段涉及到的业务接口中加入一步更新结果表中的某一个指标字段的操作。然而,这样做会导致业务之间的耦合性非常严重,可能随时影响正常业务的操作。
在中期之前,我们已经想到了使用中间表->小表的方式来进行数据处理。因此,我们能够准确地了解当前数据的变化情况,并根据变动的字段值进行相应的操作,对相关的指标字段进行增加或减少的操作。
为了解决由于多个小表同时更新统计表字段而导致的行锁问题,我们采取了进一步的优化措施,将原统计表拆分为两张表,但仍保持主键一致。这样做的好处是减少了不同小表同时更新同一行数据的情况,但需要注意的是指标字段是有所不同的。
虽然此时也满足了压测要求,但是仍然需要考虑到此项目报表的风险会影响到业务数据库的正常操作,所以将其切换到另外一个小型数据库来专门提供其查询。就算出现问题也不会影响到业务端的正常操作。
注意点:在进行当月上线之前,需要提前对统计表的各个指标进行初始化。这样可以确保数据的准确性和完整性。
上线
经过上一期的系统优化,我们成功满足了预期的压力测试结果,所有按钮和报表功能均可以正常点击和查看。值得一提的是,数据库的CPU性能一直保持在10%以下,显示了良好的稳定性。

说明:有毛刺现象是因为这个小型数据库在进行同步大表数据导致的。其实,关于结果集这种方法,在前期已经有过提出,但是我当时选择了放弃,因为存在许多不确定性因素,可能导致指标值和实际值有一定的差异。然而,目前来看,至少可以满足压测和使用的要求。
项目复盘
以上只是我在技术方面的参与和优化过程的简要描述。接下来,我将作为一个非程序员身份来对整个项目进行一个简单复盘,从一开始的项目参与到需求统计指标的制定,我一直都在其中参与,并且对这个模块非常熟悉。当第三方提出无法实现或者实现上存在困难的问题时,我通常会举例说明,因为第三方并不会像程序员一样从技术角度考虑问题。在我看来,到目前为止,一切都没有问题,因为我们已经仔细审查了每个指标,确定了哪些问题需要第三方进一步研究。
下一步就有问题了,整个项目的需求我是最了解的,但是由于我并不参与项目的开发,导致项目经理对于某一个小点根本不了解。因此,其他人经常来找我咨询,并且直到项目接近尾声时,当意识到无法满足客户的要求,才急忙找我参与开发。这是其中一个存在的问题。
让我来详细说明一下我的问题。在整个开发过程中,我的问题也逐渐显露出来,那就是为什么只有我一个人了解这个问题,而其他人却一无所知呢?原因是因为我一直在负责这个模块的开发,但是我并没有将相关的细节文档化,导致所有的细节都只存在于我的脑海中。因此,其他人只能不断地向我请教,才有可能了解这些细节。然而,这种依赖性是需要避免的,尽管我自己也很不喜欢写文档。
在项目中期时,我听到最多的抱怨之一是关于指标统计的问题。有些指标统计了多一个数,而其他指标则统计了少一个数。尽管开发工作基本上已经完成,但在核对各个数字时却出现了问题。然而,直到后期才发现这些问题其实是由于SQL编写不当所导致的。在对数据库进行操作时,我们可能没有考虑到一些边界情况或者特殊情况,导致了数据统计的不准确性。另外,还有可能是测试数据库中的数据基本都是脏数据,也就是不符合我们预期的数据,这也对统计结果造成了一定的影响。

在项目的后期阶段,由于排期已经到达客户可接受的最低底线,大家都非常着急地制定优化方案。这时候我才被真正拉过来参与,整个过程耗时将近一个月,没有休息的时间。出方案的人也开始费尽心思地想办法,但前提是他们对业务一无所知。他们也没有花时间静下心来好好思考,只管出方案,而我们这边需要再评估一下。我们花了整整一天(24小时)的时间来进行评估,具体方案和技术优化的细节我就不详细介绍了,总之最终的方案就是我之前提到的各种技术优化。
其实,我在这个过程中发现了一个规律,前期一直在进行指标分析,而后期的重点则是确保系统能够满足压力测试的要求,即客户的预期。如果下次你有类似的需求,一定要确保在系统正常运行的基础上,再去优化指标的准确性,就像这次项目,当初上线时连页面都无法打开,数据库的CPU直接达到了极限,根本没有时间去核对报表指标了。简而言之,我们需要先满足最低要求,然后逐步进行优化。
从CPU100%高危故障到稳定在10%:一个月的优化之旅,成功上线!的更多相关文章
- 10 months then free? 10个月,然后自由
Parole board to recommend Oscar Pistorius be released in August 假释委员会将建议奥斯卡·皮斯托瑞斯在8月份被释放 By Don Melv ...
- mysql 在原有的时间上加10个月或者一年
UPDATE SERVER_TIME_LEFT SET END_TIME = DATE_ADD(END_TIME, INTERVAL 10 MONTH) WHERE SHOP_ID BETWEEN 1 ...
- (转)Groupon前传:从10个月的失败作品修改,1个月找到成功 并不挶泥在这个点子上面,它反而往后站一步,看看他们已经做好的这个网站,可以再怎么包装成另一个完完全全不同的网站?所有的人所做的每件失败的事情中, 一定有碰到或含有成功的答案」在里面,只是他们不知道而已。 人不怕失败」,只怕宣布失败」
(转)Groupon前传:从10个月的失败作品修改,1个月找到成功 今天读到 一个非常励志人心的故事 ,就像现在「叶问」有「前传」,最近很火红的团集购网站Groupon 也出现了「Groupon前传」 ...
- 10个CSS简写/优化技巧-摘自网友
10个CSS简写/优化技巧23来源/作者:未知 类别:前端开发 字体大小:大|中|小 背景颜色:蓝|白|灰 ? ? CSS简写就是指将多行的CSS属性简写成一行,又称为CSS代码优化或CSS缩写.CS ...
- 在训练CNN时,loss稳定在log(类别数)
参见知乎问题! https://www.zhihu.com/question/275774218 很多框架都会有一个问题,当卷积 weight NaN 之后,卷积的 output 会变成 NaN.然后 ...
- 分享10条PHP性能优化的小技巧,帮助你更好的用PHP开发:
1. foreach效率更高,尽量用foreach代替while和for循环. 2. 循环内部不要声明变量,尤其是对象这样的变量. 3. 在多重嵌套循环中,如有可能,应当将最长的循环放在内层,最短循环 ...
- php分10个不同等级压缩优化图片
今天找到一个php写的压缩图片程序,可以分10个等级(0-9)来压缩,0等级时压缩比率不是很大,图片不会失真:随着压缩等级不断增大,图片会变得越来越不清晰,通常压缩后图片大小可以减少到原来的50%,压 ...
- Cocos2d-JS V3.10 一个小bug提示
感谢读者古事东流反馈,新版V3.10的音乐播放接口存在一个bug. 重复播放一个音乐,会出现音乐停止的状况. debug了一下,发现src的对比有点问题.传入的url是相对路径,但背景bgMusic. ...
- 【Xamarin 挖墙脚系列:Windows 10 一个包罗万象的系统平台】
build2016 结束后,证实了微软之前的各种传言.当然,都是好消息. Windows10 上基本可以运行主流的任意的操作系统. Windows Linux(在内部版本143216中,支持了bash ...
- 10.21 (上午) 开课一个月零十七天 (PHP基础语法)
<?php $a = 6; echo $a; //注释语法 /* 多行注释 */ //输出语法 echo "hello"; echo "world",&q ...
随机推荐
- Qt做大型软件开发技术选型Part2:Qt调用C#编写的COM组件
Qt做大型软件开发技术选型Part2:Qt调用C#编写的COM组件 之前有提到过我们项目部现在正在用Qt重构一个大型软件,现在的情景是这样的: 原先的软件是通过一个C++(CLR)的主程序,调用各种用 ...
- eyebeam高级设置
概述 VOIP测试过程中,经常会用到各种各样的SIP终端,eyebeam是其中最常见的一种. 在eyebeam的配置option中,只有少量的配置选项,有些特殊的设置无法配置. 比如DTMF码的发码形 ...
- 以太网链路连接 和 ISIS/OSPF等路由协议关系
转载请注明出处: 以太网链路连接和ISIS/OSPF协议之间存在关联和区别 关联: 以太网链路连接是指通过以太网物理媒介(如电缆)将网络设备进行连接,使它们可以交换数据. ISIS(Intermedi ...
- springBoot 使用 @NotEmpty,@NotBlank,@NotNull 及@Valid注解校验请求参数
本文为博主原创,转载请注明出处: @NotEmpty,@NotBlank,@NotNull 这些注解所在的jar包路径在 javax.validation.constraints 的包下面,这个包下面 ...
- AMBA Bus介绍_01
AMBA总线概述 系统总线简介 AMBA 2.0 AHB - 高性能Bus APB - 外设Bus AHB ASB APB AHB 组成部分 APB组成部分 AMBA协议其他有关问题 DMA DMA ...
- 05-Shell索引数组变量
1.介绍 Shell 支持数组(Array),数组是若干数据的集合,其中的每一份数据都称为数组的元素. 注意Bash Shell 只支持一维数组,不支持多维数组. 2.数组的定义 2.1 语法 在 S ...
- 使用QQ屏幕识图实现识别表格功能
1.问题 目前市场上的OCR工具对于识别表格功能均是采取了收费制度,但我们时常要进行一些表格的复制(原表格为图片) 便可以使用QQ或钉钉自带的功能来实现 2.解决 1.QQ屏幕识图 先使用屏幕识图功能 ...
- 【Altium Designer】五颜六色标识的PCB布板(增强PCB可视化特性)
出现上图中五颜六色的网络标识,对比各个网络会更加清晰,实现步骤如下 打开或关闭 View--->Net Color Override Active 快捷键 F5 设置 displa ...
- Spring————IOC入门学习
Spring----入门学习 简介 优点 Spring是一个开源的免费的框架(容器)! Spring是一个轻量级,非入侵式的框架 控制反转(IOC),面向切面编程(AOP) 支持对事务的处理,对框架整 ...
- 百度网盘(百度云)SVIP超级会员共享账号每日更新(2023.12.26)
一.百度网盘SVIP超级会员共享账号 可能很多人不懂这个共享账号是什么意思,小编在这里给大家做一下解答. 我们多知道百度网盘很大的用处就是类似U盘,不同的人把文件上传到百度网盘,别人可以直接下载,避免 ...