引言

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

初期优化

在进行第一次优化时,我们发现SQL的基本书写存在问题。通过使用pinpoint工具,我们成功抓取了所有的SQL语句。然后,我们请一位对业务非常熟悉的人对所有的SQL进行了审查,主要是优化SQL书写中的基本错误。由于开发人员的疏忽,导致了数据库的全表查询,但是由于测试数据库的数据量不足,测试环境并没有发现潜在的基础SQL问题。经过第一轮SQL优化,现在所有的SQL语句已经得到了正确的修正。

经过压力测试后,我们发现数据库的CPU已经超负荷运行。为了进一步优化性能,我们决定进行SQL的详细优化。在查询表关联的过程中,我们发现有很多字段实际上已经在业务表中冗余存在,因此无需再去关联另外一张表。通过减少表的关联操作,我们可以有效提高SQL的执行效率。

中期优化

由于测试数据量不足且业务关联性较差,我们需要申请将正式数据库中涉及的表数据迁移至测试数据库,以模拟正式环境进行压力测试。

经过初步讨论,我们认为业务表的数据量很大可能导致了SQL查询的缓慢和CPU性能的占用。为了优化这个问题,我们决定根据所有报表涉及的表及其字段,扫描业务增量数据并抽离出一个小表用于报表业务查询。

在进行数据迁移的过程中,我们要注意的是,除非数据量很小的表,不要直接将其抽离到小表中。相反,我们需要引入一个中间表来提前缓冲数据。如果直接去除中间表,可能会导致对业务表的锁定,从而降低业务操作的性能。

注意点:在上线之前,务必确保准备好初始化表数据和相应的表索引。丢失一个都会导致生产数据库的CPU跑满。

后期优化

由于项目需要进行时间范围查询,当选择以月为单位时,首页在压测并发下未能达到预期要求。因此,我们进行了方案升级,引入了结果表的概念。具体而言,我们按照月份的最小统计范围提前生成结果统计表。也有人提出在此阶段涉及到的业务接口中加入一步更新结果表中的某一个指标字段的操作。然而,这样做会导致业务之间的耦合性非常严重,可能随时影响正常业务的操作。

在中期之前,我们已经想到了使用中间表->小表的方式来进行数据处理。因此,我们能够准确地了解当前数据的变化情况,并根据变动的字段值进行相应的操作,对相关的指标字段进行增加或减少的操作。

为了解决由于多个小表同时更新统计表字段而导致的行锁问题,我们采取了进一步的优化措施,将原统计表拆分为两张表,但仍保持主键一致。这样做的好处是减少了不同小表同时更新同一行数据的情况,但需要注意的是指标字段是有所不同的。

虽然此时也满足了压测要求,但是仍然需要考虑到此项目报表的风险会影响到业务数据库的正常操作,所以将其切换到另外一个小型数据库来专门提供其查询。就算出现问题也不会影响到业务端的正常操作。

注意点:在进行当月上线之前,需要提前对统计表的各个指标进行初始化。这样可以确保数据的准确性和完整性。

上线

经过上一期的系统优化,我们成功满足了预期的压力测试结果,所有按钮和报表功能均可以正常点击和查看。值得一提的是,数据库的CPU性能一直保持在10%以下,显示了良好的稳定性。

说明:有毛刺现象是因为这个小型数据库在进行同步大表数据导致的。其实,关于结果集这种方法,在前期已经有过提出,但是我当时选择了放弃,因为存在许多不确定性因素,可能导致指标值和实际值有一定的差异。然而,目前来看,至少可以满足压测和使用的要求。

项目复盘

以上只是我在技术方面的参与和优化过程的简要描述。接下来,我将作为一个非程序员身份来对整个项目进行一个简单复盘,从一开始的项目参与到需求统计指标的制定,我一直都在其中参与,并且对这个模块非常熟悉。当第三方提出无法实现或者实现上存在困难的问题时,我通常会举例说明,因为第三方并不会像程序员一样从技术角度考虑问题。在我看来,到目前为止,一切都没有问题,因为我们已经仔细审查了每个指标,确定了哪些问题需要第三方进一步研究。

下一步就有问题了,整个项目的需求我是最了解的,但是由于我并不参与项目的开发,导致项目经理对于某一个小点根本不了解。因此,其他人经常来找我咨询,并且直到项目接近尾声时,当意识到无法满足客户的要求,才急忙找我参与开发。这是其中一个存在的问题。

让我来详细说明一下我的问题。在整个开发过程中,我的问题也逐渐显露出来,那就是为什么只有我一个人了解这个问题,而其他人却一无所知呢?原因是因为我一直在负责这个模块的开发,但是我并没有将相关的细节文档化,导致所有的细节都只存在于我的脑海中。因此,其他人只能不断地向我请教,才有可能了解这些细节。然而,这种依赖性是需要避免的,尽管我自己也很不喜欢写文档。

在项目中期时,我听到最多的抱怨之一是关于指标统计的问题。有些指标统计了多一个数,而其他指标则统计了少一个数。尽管开发工作基本上已经完成,但在核对各个数字时却出现了问题。然而,直到后期才发现这些问题其实是由于SQL编写不当所导致的。在对数据库进行操作时,我们可能没有考虑到一些边界情况或者特殊情况,导致了数据统计的不准确性。另外,还有可能是测试数据库中的数据基本都是脏数据,也就是不符合我们预期的数据,这也对统计结果造成了一定的影响。

在项目的后期阶段,由于排期已经到达客户可接受的最低底线,大家都非常着急地制定优化方案。这时候我才被真正拉过来参与,整个过程耗时将近一个月,没有休息的时间。出方案的人也开始费尽心思地想办法,但前提是他们对业务一无所知。他们也没有花时间静下心来好好思考,只管出方案,而我们这边需要再评估一下。我们花了整整一天(24小时)的时间来进行评估,具体方案和技术优化的细节我就不详细介绍了,总之最终的方案就是我之前提到的各种技术优化。

其实,我在这个过程中发现了一个规律,前期一直在进行指标分析,而后期的重点则是确保系统能够满足压力测试的要求,即客户的预期。如果下次你有类似的需求,一定要确保在系统正常运行的基础上,再去优化指标的准确性,就像这次项目,当初上线时连页面都无法打开,数据库的CPU直接达到了极限,根本没有时间去核对报表指标了。简而言之,我们需要先满足最低要求,然后逐步进行优化。

从CPU100%高危故障到稳定在10%:一个月的优化之旅,成功上线!的更多相关文章

  1. 10 months then free? 10个月,然后自由

    Parole board to recommend Oscar Pistorius be released in August 假释委员会将建议奥斯卡·皮斯托瑞斯在8月份被释放 By Don Melv ...

  2. mysql 在原有的时间上加10个月或者一年

    UPDATE SERVER_TIME_LEFT SET END_TIME = DATE_ADD(END_TIME, INTERVAL 10 MONTH) WHERE SHOP_ID BETWEEN 1 ...

  3. (转)Groupon前传:从10个月的失败作品修改,1个月找到成功 并不挶泥在这个点子上面,它反而往后站一步,看看他们已经做好的这个网站,可以再怎么包装成另一个完完全全不同的网站?所有的人所做的每件失败的事情中, 一定有碰到或含有成功的答案」在里面,只是他们不知道而已。 人不怕失败」,只怕宣布失败」

    (转)Groupon前传:从10个月的失败作品修改,1个月找到成功 今天读到 一个非常励志人心的故事 ,就像现在「叶问」有「前传」,最近很火红的团集购网站Groupon 也出现了「Groupon前传」 ...

  4. 10个CSS简写/优化技巧-摘自网友

    10个CSS简写/优化技巧23来源/作者:未知 类别:前端开发 字体大小:大|中|小 背景颜色:蓝|白|灰 ? ? CSS简写就是指将多行的CSS属性简写成一行,又称为CSS代码优化或CSS缩写.CS ...

  5. 在训练CNN时,loss稳定在log(类别数)

    参见知乎问题! https://www.zhihu.com/question/275774218 很多框架都会有一个问题,当卷积 weight NaN 之后,卷积的 output 会变成 NaN.然后 ...

  6. 分享10条PHP性能优化的小技巧,帮助你更好的用PHP开发:

    1. foreach效率更高,尽量用foreach代替while和for循环. 2. 循环内部不要声明变量,尤其是对象这样的变量. 3. 在多重嵌套循环中,如有可能,应当将最长的循环放在内层,最短循环 ...

  7. php分10个不同等级压缩优化图片

    今天找到一个php写的压缩图片程序,可以分10个等级(0-9)来压缩,0等级时压缩比率不是很大,图片不会失真:随着压缩等级不断增大,图片会变得越来越不清晰,通常压缩后图片大小可以减少到原来的50%,压 ...

  8. Cocos2d-JS V3.10 一个小bug提示

    感谢读者古事东流反馈,新版V3.10的音乐播放接口存在一个bug. 重复播放一个音乐,会出现音乐停止的状况. debug了一下,发现src的对比有点问题.传入的url是相对路径,但背景bgMusic. ...

  9. 【Xamarin 挖墙脚系列:Windows 10 一个包罗万象的系统平台】

    build2016 结束后,证实了微软之前的各种传言.当然,都是好消息. Windows10 上基本可以运行主流的任意的操作系统. Windows Linux(在内部版本143216中,支持了bash ...

  10. 10.21 (上午) 开课一个月零十七天 (PHP基础语法)

    <?php $a = 6; echo $a; //注释语法 /* 多行注释 */ //输出语法 echo "hello"; echo "world",&q ...

随机推荐

  1. 2.5D 组态案例合集 | 智慧园区、数据中心、SMT 生产线、汽车制造

    在阅读文章之前,大家可以思考下 2.5D 设计属于哪种界定? 2.5D 是通过二维的元素来呈现出三维的效果.其实在国外并没有 2.5D 这样的称呼,标准说法是 Isometric 风格,翻译过来就是等 ...

  2. Redis无法使用ip访问

    问题:    启动redis服务,可以使用127.0.0.1配置并使用访问redis,但是换成IP地址就无法访问 127.0.0.1 可以 [root]#  ./redis-cli -c -h 127 ...

  3. warning: LF will be replaced by CRLF in public/tinymce/langs/zh_CN.js

    windows使用git时出现:warning:LF will be replaced by CRLF windows中的换行符为 CRLF, 而在linux下的换行符为LF,所以在执行add . 时 ...

  4. Redis 常用五种数据类型编码

    转载请注明出处: 目录 Redis 的五种数据结构 Redis 数据结构的内部编码 1.String 1.1 常用命令 1.2 内部编码 1.3 典型使用场景 2. Hash 2.1 常用命令及时间复 ...

  5. Redis 主从复制架构配置及原理

    本文为博主原创,未经允许不得转载: 目录: 1. Redis 主从复制架构搭建 2. Redis 主从架构原理 3. Redis 断点续传 4. Jedis 连接 redis 主从架构一般配置一主多从 ...

  6. Angular系列教程之依赖注入详解

    .markdown-body { line-height: 1.75; font-weight: 400; font-size: 16px; overflow-x: hidden; color: rg ...

  7. JS逆向实战27——pdd的anti_content 分析与逆向

    声明 本文章中所有内容仅供学习交流,抓包内容.敏感网址.数据接口均已做脱敏处理,严禁用于商业用途和非法用途,否则由此产生的一切后果均与作者无关,若有侵权,请联系我立即删除! 本文已在微信公众号发布 目 ...

  8. 【深入解读Redis系列】(五)Redis中String的认知误区,详解String数据类型

    有时候博客内容会有变动,首发博客是最新的,其他博客地址可能会未同步,请认准https://blog.zysicyj.top 首发博客地址 系列文章地址 需求描述 现在假设有这样一个需求,我们要开发一个 ...

  9. [转帖]浪潮PM8222-SHBA、RAID 2GB PM8204、RAID 4GB PM8204,阵列卡配置方法

    1.8222和8204对比 这几个型号的阵列卡都很相似,配置方法也基本一样 8204就是在8222上的基础上增加了缓存,可以通过下图对比 正面8204比8222多一个掉电保护接口 8204背面多了几个 ...

  10. [转帖]【SQL SERVER】锁机制

    https://www.cnblogs.com/WilsonPan/p/12618849.html   锁定是 SQL Server 数据库引擎用来同步多个用户同时对同一个数据块的访问的一种机制. 基 ...