一段未经测试的功能代码上生产导致整个系统崩溃长达一个星期

我们在学习编程开发流程中,老师苦口婆心地叮嘱我们:本地代码调通后,必须到测试环境再走一遍后才能发生产环境。实际工作过程中,经理工作不认真且管理宽松加上部分素质不佳的程序员贪图方便跳过测试环境直接上生产。这个不安全且危险的操作,究竟能造成多大危险呢?今天让我跟大家讲解一下吧!

先说说背景,本人在一家制造企业的IT中心当一名普通的程序员,专门帮助公司搭建信息化系统来应对企业目前以及未来发展所带来的业务冲击(甲方)!我们为了方便快捷的搭建属于自己的信息化系统,决定购买市场上成熟的产品来实现并且花大价钱请了金蝶来承担这项工作(乙方)。本文故事主角就出在乙方的实施工程师上面。

事情的经过:本人正在办公室里苦逼的敲着代码,产品这边突然一个电话过来说:“系统崩溃了,流程转不起来”一听这个,心凉了半截,二话不说,马上访问系统。诡异的事情就来了,系统正常访问,流程却不能跳转。上服务器查资源利用情况,发现也正常运行,联系乙方运维工程师,也说正常运作。一时之间,整个人都是懵圈的,系统已经正常运行一年有余,霎时间部分功能运作异常,只有最近发版导致的。最近只有自己发过一版,但是发完后也正常运作,我的发布内容也没有设计流程相关代码。苦想之后,只能向金蝶总部提报故障了。对面也挺有意思,马上组织了一个专门解决小组攻关解决。小组从4人小组扩充到18人,历经32个小时的艰苦卓绝排查后,终于把问题查出来了。

原因:一个发布以久的插件由于没做业务终止判断导致循环推送大量微信通知导致线程阻塞。该问题由于根据业务订单量增加到一定量后才体现出来,具有高度隐蔽特性。不幸的是,昨天触发了。至于怎么查出来的?还是要查系统的推送日志看出一点端倪,一个账号同一时间,推送了将近3亿次!!!后面一查是乙方的实施工程师帮我们开发的通用微信推送类导致的。

以下就是故障代码(初步归类:业务不作闭环控制出现类死循环导致系统阻塞):

/**
    	 * 二开公司负责插件,运行逻辑出现功能性阻塞,
    	 * 原因:初步分析,迭代出现阶乘处理,也没有做闭环控制,导致类死循环出现,系统崩溃
    	 * 解决方案:该插件注释停用,不予运行
    	 */
        String condition = (String) map.get("condition");
        if ("purOrder".equals(condition)) {
            List<Long> userIds = new ArrayList<>();
            DynamicObject[] objects = BusinessDataServiceHelper.
                    load("pur_order", "supplier.id,id",
                            new QFilter[]{new QFilter("billstatus", "=", "C"),
                                    new QFilter("batf_combofield", "=", "1")});//查询已审核且没推送的采购订单推送微信通知用户
            for (DynamicObject object : objects) {
                Long supplierId = object.getLong("supplier.id");
                Long id = object.getLong("id");
                userIds.addAll(CQUtils.getSupplierUserBySupplier(supplierId));//这货将所有用户id放进列表里推送,导致每次推送次数以阶乘计算(订单数!)

                if (userIds.size() > 0) {
                    MessageInfo message = WeixingzhHandler.initMessageInfo("订单待确认提醒", userIds,
                            "pur_order", "MSGBatf007", "confirm", id, "batf_scene004");
                    MessageCenterServiceHelper.sendMessage(message);//推送消息
                }
            }
            System.out.println(DateTime.now());
//最后也没有已推送的采购订单标志为“已推送”,两个原因导致同一时间推送了3亿次
        }

原理简单,但结果隐蔽且严重,要不是金蝶总部老师仔细负责还真的能把系统压垮!

处理结果:把该插件停用注释掉。

猜你喜欢

转载自blog.csdn.net/lijinquan2009/article/details/124452189