记一次性能优化
五月的某一天,突然从客服处得知……使用我司APP的用户群体中井喷式的出现“网络错误”。司里就我一个后台开发,由于手头掌握的工具和资源都不多,甚至回家后都没有一台可以办公的电脑,处理这种问题还真的难到我了……
第一步,检查网络。
难道真的是服务器的网络出问题了吗?在认真阅读了入口服务器的代理配置文件后,我陷入了沉思……一台最高带宽只有10M的服务器上,居然设置了很多超过1M的资源,……并且是可频繁访问的那种模式。
于是,我花了不少时间整理这些资源,并将他们转移到了其他服务器。话说其他服务器也不宽裕,但总不能让网络问题存在关键结点上吧。O(∩_∩)O
然后接下来的一天,到了那个用户高峰期时,还是卡了;尽管有了些许不明显的改变——至少,这些改变不是领导们想看见的。
第二步,咨询云服务供应商。
由于服务器不是自己搭建的,近期又正好改了个奇怪的配置(对方正在测试、未正式上线的那种),不得不让人怀疑这里会有问题。
于是,我找到了供应商售后客服;对方查询了近期的网络性能跟踪图表后,得出一句话:带宽方面没有出现什么异常。
虽然对方没有发任何图片给我看,仅是难以让人信服的一句话;但作为一个小开发,我们也只能选择相信他。
第三步,优化分布式服务的结点结构。
小公司的财力总是有限的,我们很多时候不得不把海量服务堆在一台配置比较古老的服务器上。使用开源软件也是一种必然,因为免费……而且性能够用。
经过再三思索后,我取消了几个已经过期的服务,甚至还删除了它们的代码库;在当前分析的这个APP范畴中,三台服务器分别做httpd代理、数据库、缓存,所以,三台服务器的资源消耗分别偏向于带宽、CPU、内存。
既然云服务器供应商坚持认为带宽方面没有问题,那么我们就要从其他两个角度来考虑了。
先把数据库所在服务器的非必须的java服务全部干掉了……免费的数据库,性能再好也不能寄予太高期望。其次,又将缓存服务器上多余的数据服务也干掉了;历史上是准备拿他做备份的。但资源有限,先不备份了……小公司,资金有限,单机罗本也不是奇怪的事,此处我暂时不觉得有多尴尬。。。
最后,观察一个晚上后,又在代理服务器上起了几个java服务……没办法,结点少了会导致APP平时的体验都很差。
第四步,数据缓存。
缓存服务器的总内存是16G,如今已经用了10G;考虑到该设备上的其他nosql数据服务……(小公司、正常的,多理解即可)……总得留几个G来预备瓶颈。所以先预支了2G空间来缓存服务需要的数据库操作。不敢设置太久的expire时间,2个小时吧。数据堆积太久了,我担心这台设备内存会爆炸。
观察一晚上后,发现高峰期还是有时候会网络异常……
走了这么多步优化路线,咋还异常呢?看来还得再往深处挖一挖。
第五步,数据库优化。
进入数据库,发现七八张已经过期的中间表,其中一张数据量近1KW……没得说,直接干掉,然后搜索后台所有代码,把关联代码也解耦、上线。
另有十张疯狂的数据表,都是几百万级别,这对免费版数据库,确实是个不小的折磨;思考良久后,根据各大小系统代码关联关系,每张表上了6个索引……内存上去了,但性能实打实的得到了一些提升。
做完这些,发现还是卡。崩溃……
逐个表检查DDL,结果终于被我找到了,一个超强的触发器……嗯,检查了十多个项目持久层代码后,果断决定干掉它。
还有几个事件,检查了很多次,发现业务很重要,不能删,只好忍痛留着。
数据库的CPU占用率终于从80%+处就此降了下来,日常10%不到,偶尔往上飘一下,处理完又会降下来……比之前确实健康多了。
第六步,代码逻辑优化。
尽管这样,在五天后,居然又收到了一个“网络错误”的客诉……当时记得我心态都差不多崩了。
经过详细的对接后,我发现是后台一些代码写的有问题;看来上一位开发离职还是有深层次原因的……循环中使用大规模的并发运算,挺好的;几百条数据,硬是算出了一万年的效果。
嗯,其核心是一个计算星期的方法。然而,……计算星期很难么?我毫不犹豫扑了上去……
半个小时后,一个新的方法出炉,测试任何情况的输入参数时,整个运算耗时也就十几个毫秒,完美。
一样的循环,只是循环里调了不一样的方法……Java并没有随着时代的发展,而任由我们随意写代码;写代码还是老程序员靠谱。。。/哭
最后:展望未来
前任哥们写的Java代码里头,还有几个远程调用相互嵌套的……看的头疼,慢慢改吧。
数据库分出来的表都有百万数据了,产品表示要完全保留历史数据……嗯,挺好的,又多一个需要思考的问题。
此外,最致命的还是缓存服务器了,和某nosql同一设备,公司拒绝加内存……这简直无解啊。
未来就是这么奇幻,老程序员依然任重而道远。