SCPPO(二十九):测算过程中问题的解决总结(续)

 

【前言】

    小编在上篇博文(建议朋友们回顾一下,请点击我---SCPPO:测算过程中问题的解决总结)中为大家分享了测算的业务以及出现的测算慢的原因和一种解决方案。

    系统只要有人使用会出一些Bug解决Bug一方面使得团队能力提高,另外使得甲方使用的更顺手;一个中大规模的系统要想长久的为人们创造价值,必然需要不断的修改Bug和重构。

【无Bug不编程】

    一、顽强Bug的由来:

      上次采用去数据库校验修改成单线程的版本是在11月24号完成的,25号进行的部署;修改完的这版系统真正使用的企业只有5家,当时进行挺顺利,没发现问题,在后台检测也未发现有死锁的情况;

      本想这个缓兵之计非常不错,正所谓:天将降大任于斯人也必先,苦其心志、、、上天还是蛮眷顾我,当12月份24号来临时仿佛一切都不是那么美好了;各种问题各种出,不仅并发的情况再次出现而且平均的测算时间不降反升。领导非常重视测算,组长和我也不敢稍有怠慢,于是乎一场分析修改Bug的大战就此拉开帷幕。

    二、经典Bug之战:

      1、并发战役(一)---前台血拼

        (1)问题描述:

             同一个企业在连续点击时出现并发,见下截图:

         

        (2)原因分析:

            企业在快速点击时Ajax先去执行,等Ajax执行完后再将按钮变为不可用,当中有时间差,企业在连续点的时候会出现上述情况。

           

        (3)解决方案:

             在测算方法开始执行时先将按变为不可用,然后再通过Ajax调用后台的方法,相关代码如下截图:

            

      2、并发战役(二)---后台争雄

        (1)问题描述:

            在数据库中进行检测发现了死锁的情况(如下截图),同一个企业在14:13:55和14:14:06(此时14:13:55开启的测算并未执行完)开启了两次测算;

    

        (2)原因分析:

             14:13:55开始执行存储过程,去触发总的存储过程(包含30个子存储过程,见下截图),先是执行第一个存储过程,执行完后再向[JobLog]中插入,执行这个存储过程时间段:14:13:55——14:15:53,而在14:14:06这个点点击测算,界面校验逻辑:搜索JobLog,ID最高的一条看其是不是最后一个存储过程,这时14:13:55的开始的测算第一个存储过程还未执行完,即JobLog表中还没有插入14:13执行第一个存储过程,所以在14:14:06时校验仍为可以测算。

 

        (3)解决方案:

             修改存储过程:在开始第一个存储过程就在JobLog表中插入一条记录,以此来避免第一个存储过程执行的时间差。

 

      3、卡死战役---谁与争锋

        (1)问题描述:

             有一家企业在测算时执行77%的存储过程需要大概半个小时,组长带入参数执行该存储过程在数据库中执行可以完成,但是用系统执行时时间长就报错;

        (2)原因分析:

           ①对比手动执行和用系统执行问题出在系统代码上,对比上个月镇海执行(上个月执行1分钟)和这个月执行问题出在时间上。跟踪代码发现有执行时间限制;

        (3)解决方案:

             ①跟踪代码发现有执行时间限制;

               

             ②将CommandTimeout(时间为s,值默认为30,0为不限制时间)的值从1800修改为1000*60*60      

      3、决战---拨开云雾见青天

        (1)问题描述:

             经过上面几场战役后,终于会战最后的大Boss---不时的有并发情况,执行时间长。

        (2)原因分析:

             ①和数据量有关,相关测试:同样的代码在测试服务器上对9月份的某企业数据进行测试,很快就执行完毕;而测试同样的企业在正式服务器(为何用正式服务器测试12月份---测试服务器所连的测试库中无12月份的数据并且正式服务器的9月份数据不能随便测试)上的12月份数据则很慢。

             ②页面加入单线程的校验,但是Controller中未加入单线程校验时,导致有的企业会出问题,死锁住;相关验证如下:

               a.只在界面中加入单线程的校验,Controller中未加单线程出现死锁时的情况:

             

               b.在Controller中加入校验方法,多个企业同时点测试的话(Controller未加入校验,多个企业点出现死锁情况①),没有出现死锁情况:

                (a)加校验的地方:

 

                (b)加完校验再次测试,用本机(网比较慢),发现会出现可以多点,点完后等会儿出现多个弹出框,界面会卡死(不进行1s的校验),但是运行完后会恢复(长时间等待界面卡死);数据库中查询没有发生死锁:

 

                (c)效果展示:

          

        (3)暂时得出的结论:

             a.单个时间长和数据量有关(有待正式数据库同步到测试服务器上做测试);
             b.出现死锁情况和前台校验以及网络有关;

        (4)后续测试:

             a.问题描述:上述的修改部署完后还有企业需要集中的进行测算,测试人员一直反应有说企业特别慢;

             b.原因分析:此时登录证书数据库服务器查看服务器的性能,如下图:

                   

              c.后台检测:

                (a)没有企业在进行测算,发现正式服务器的压力比较大(CPU持续在80%以上,内存持续在93%

                (b)有企业进行测算时正式服务器压力更大(CPU持续在90%以上—有段时间持续在100%,内存持续在93%

                (c)猜测:根据这个情况猜测,单线程的校验方式是企业进入测算界面后就会执行一个每隔1s(或0.5s)的校验(参考:SCPPO:自动刷新实现),测算期间企业比较集中在此界面,导致很多访问数据库的校验导致数据库的负载比较大。

                (d)验证猜想:和组长商量后恢复到之前的版本(未加入单线程校验),中午恢复部署后,下午企业再进行测算时间快了很多,这时再监测正式数据库服务器的负载,发现CPU一下降下来(如下图所示),但是内存未降下来,猜测重启服务器后内存会降下来。

           

                (e)未来解决方案的探讨:

                    ①根据上面的测试过程来看,测算中加单线程问题所在:根据数据库的负载检测来看,是大家伙儿集中测算的时候,很多企业在测算界面,只要留在测算界面,就会每隔1s去数据库中查一下是否有其他企业正在测算,导致数据库的负荷比较大。

                    ②探究解决方法:当初在讨论设计用单线程的时候有两种方式(参见:SCPPO:测算过程中问题的解决总结)一是采取去数据库中查的方式,二是采取在Redis中放入标识变量的方式;由于当时考虑到在Redis中放入变量会增加一个故障点,所以采取去数据库中查的方式;实践来看去数据库中查压力太大,可以尝试一下往Redis中存变量来实现。 

    三、小结:     

      1、单线程实现方式:

        (1)去数据库中表读JobLog表来校验,上述实验验证数据库压力太大,不可行。
        (2)换用另外一种解决方案:存储过程执行完成后记录到Redis中,然后检验是否有正在进行的存储过程从Redis中做校验,这样减少数据库的压力
        (3)做单线程时为防止快速双击解决:
            ①不仅要在前台(比如:js)中做校验,还要在后台(比如:Controller中做校验)
            ②在点击测算时加入弹出框,提示是否开始进行测算
            ③在点击测算时输入验证码

      2、梳理30个存储过程:

         可通过SQLServer进行调试存储过程,参考:设置SQL Server 2005允许远程调试存储过程

【总结】

       1、有压力才有动力;

       2、遇到问题要大胆假设,小心求证;实践是检验真理的唯一标准;

       3、交流沟通共享这个时代的主旋律。

   

当年的春天 CSDN认证博客专家 分布式 Spring Redis
6年Java互联网研发经验,坐标北京;擅长微服务和中间件。
已标记关键词 清除标记
©️2020 CSDN 皮肤主题: 博客之星2020 设计师:CY__0809 返回首页
实付 9.90元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值