慢接口性能优化建议

最近优化了项目中,慢接口的业务逻辑,得出一些心得

       最近发现一个生产问题,一个接口突然间提示异常,查日志,提示是feign接口超时,其实数据已经执行完了,只不过超过了feign设置的超时时间(60s),然后前端跳出了框架统一封装的异常信息

出现原因:

        平时的业务量基本都是十几笔,几十笔,上百笔这样的业务数据,但是这次突然来了一次超过500笔的业务数据,整个过程都是复杂的业务处理,后端处理几乎要经过5个表这样去取数,并且还要做一些金额的计算等,所以这个耗时就急速上升了。由于代码都没有做过性能的测试,所以一下次就垮了。业务经理以为系统出了问题,投诉到了技术部。

        因为已经定位到了具体的接口,所以单独拿出来,请求开始的代码逻辑到请求结束的代码逻辑,梳理了一遍,发现是那种所谓的陈年旧代码,屎山,很多影响性能方面的操作:

        一、500+笔业务进入接口,入参是String,且是逗号分隔符拼接,如:String str = "aaaa,bbbbb,ccccc",看到这个差点气晕,这个平时还好没有超长,超长了一样被投诉

        二、500+笔业务进入请求,需要拿这500+笔的业务流水号去查数据,由于这些数据存储的表,是一张很大的表,字段特别长,没具体数,上百个是有的,此时内心一万个草泥马,谁做的表设计,并且询问过,这个表n处在使用,不可以做表水平拆分

        三、500+笔业务流水去查多个表的时候,是for循环一笔笔去查的,一个表500次mybatis的selectById,大概有5个表,那就是2500次去数据库查,效率异常的底下,甚至还有的是for循环里面再for的

        四、500+笔业务流水昨晚数据处理后,需要插入到数据,或者有的表是做更新的,for循环insert和for循环updateById

        以上是经过了1天的梳理,得出导致性能差的代码,想起一句经典的话:jvm一般是不需要调优的,要调优的都是垃圾代码导致的!!!!!

程序员还是应该具备基本的代码优化能力,什么for循环去查数据库,一般要避免这种情况,能一次lou出来就一次,跟数据库只做一次交互,提升性能

开始第一次重构代码:

        一、把接口入参String改成List<String>

        二、业务大表没办法拆,只能使用主键索引去查,用in('aaa','bbb','ccc')的方式一次性查出来,避免for里面再selectById,如这时候不是500+,是1000+的话,则对List<String>做一个切割,1000笔查一次,否则in超过1000笔会报错。对list切割可以自己写一个时间复杂度最低的算法,也可以用guava的list切割省事

        三、缕了一次逻辑之后,发现,可以并行的去查多个表,使用异步编排CompleteFuture,并行去执行任务,不需要串行查表

        四、for循环入库和更新,换成mybatisplus的saveBatch,和updateBatch,批次执行,500一次或者1000一次

修改后第一次测试:

        本地模拟了生产的数据量500+笔数据发起业务,没改代码前复现了同样超时问题,执行了2分多种。经过上诉优化后,提升到了20s左右,个人感觉还不适合理想,用arthas检测了下哪个方法执行耗时情况,发现耗时还是在mybatis取数据时候:

        一、mybatis默认取数是10条一次,然后再继续取,直到取完,所以在数据库执行是变快了,但是用mybatis执行任然有差异

        二、for循环里面做复杂处理和计算时,也会有性能消耗,如:getName这样的操作,每次for里面执行一次,那就是500次,如果有多次调用,那就是500*n,虽然都是ms级别,但是多了这个数量还是很客观的。

        三、监控jvm内存会一下次暴增,垃圾回收会很频繁,但是好消息是没有fullgc

针对问题第二次重构代码:

        一、mybatis每次取数扩大,xml增加参数:fetchSize="100",经过测试100跟1000相差不大,使用保守100

        二、for循环里面如果有一个参数要多次使用,第一次getName的时候,提出来做一个本地变量,节省500*n的耗时

        三、修改sql语句,大数据表取行数时,只取需要的字段,如:一个表有100个字段,只取需要的5个字段,select A,B,C,D,E from table,经测试可以节省堆空间消耗,冗余字段不需要,因为如果一起带出来赋值给对象时候会生成String对象,占用堆空间

        四、把for循环换成JDK1.8的foreach内部循环(不用不知道,一用吓一跳,复杂计算内部循环会节省很多消耗,但是笔数没达到一定数量,是没啥区别的)

修改第二次测试:

       相同参数再次执行请求,响应时间上到8s内,此刻的主角爽度+100,继续用arthas监控,之前的mybatis取数跟循环for操作耗时已经在1s上下了,而且jvm的垃圾回收次数有相应的减少,目前所有耗时全都在insert跟update里面,入库跟更新表需要消耗IO,这个确实是感觉无法优化了(有想过多线程去入库,但是涉及子线程事务控制,比较复杂,最终放弃),最后版本修复,生产继续做相同业务,已经可以正常执行,并且执行比本地快,3s左右就可以响应,果然还是生产服务器好啊,码农板砖能用就行啊。。。

小结:

        一顿优化之后,深刻体会到了开发应该具备良好的编码习惯,不规范的代码不要去写,这样可以避免很多未来会产生的问题,少bug,多摸鱼。可去阅读《阿里的代码规范手册》,《effective java》,《代码的整洁之道》这些书记,提升内功,完结撒花~~~

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,366评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,521评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 165,689评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,925评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,942评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,727评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,447评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,349评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,820评论 1 317
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,990评论 3 337
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,127评论 1 351
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,812评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,471评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,017评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,142评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,388评论 3 373
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,066评论 2 355

推荐阅读更多精彩内容