테스트되지 않은 기능 코드 조각으로 인해 일주일 동안 전체 시스템이 중단되었습니다.

프로그래밍과 개발 과정을 배울 때 선생님께서 진지하게 말씀하셨습니다. 로컬 코드를 조정한 후 테스트 환경으로 가서 다시 거쳐야 프로덕션 환경을 만들 수 있습니다. 실제 작업 과정에서 관리자는 업무에 진지하지 않고 관리도 허술했으며, 품질이 좋지 않은 일부 프로그래머는 테스트 환경을 건너뛰고 직접 생산에 들어가려고 애썼다. 이 안전하지 않고 위험한 작업은 얼마나 위험할 수 있습니까? 오늘은 그 내용을 설명해드리겠습니다!

배경부터 먼저 이야기하자면, 저는 제조 회사의 IT 센터에서 일반 프로그래머로 일하고 있으며, 회사의 현재와 미래 발전이 비즈니스에 미치는 영향에 대처하기 위한 정보 시스템 구축을 전문으로 하는 회사입니다(A측)! 우리 자신의 정보 시스템을 편리하고 신속하게 구축하기 위해 우리는 시장에서 성숙한 제품을 구매하여 이를 구현하기로 결정하고 이 작업을 수행하기 위해 Kingdee를 큰 가격에 고용했습니다(파티 B). 이 글의 주인공은 B당의 구현 엔지니어이다.

경위: 사무실에서 열심히 코드를 치고 있는데 갑자기 제품측에서 "시스템이 다운되어 프로세스를 시작할 수 없습니다"라는 전화가 왔습니다. 한마디, 바로 시스템에 접속했습니다. . 여기서 이상한 점은 시스템에 정상적으로 접근할 수는 있지만 프로세스를 점프할 수는 없다는 것입니다. 서버의 리소스 활용도를 확인해 보니 정상적으로 실행되고 있는 것을 확인하였고, B측 운영 및 유지보수 엔지니어에게 연락했더니 정상적으로 실행되고 있다고 합니다. 잠시 모두가 혼란스러워 했습니다.1년 넘게 시스템이 정상적으로 작동하고 있었는데 갑자기 일부 기능이 비정상적으로 작동하는 현상이 최근 릴리스에서만 발생했습니다. 최근에 한 가지 버전만 퍼블리싱했는데, 퍼블리시한 후에는 정상적으로 작동했습니다. 제가 퍼블리싱한 콘텐츠에는 디자인 프로세스와 관련된 코드가 없습니다. 곰곰이 생각한 끝에 킹디 본사에 잘못을 보고할 수 밖에 없었습니다. 반대편의 상황도 꽤 흥미로웠고, 문제를 해결하기 위해 즉시 특별 솔루션 팀이 구성되었습니다. 팀은 4명에서 18명으로 확대됐고, 32시간의 고된 조사 끝에 마침내 문제가 발견됐다.

이유: 오래 전에 출시된 플러그인이 사업 종료 판단을 내리지 않아 수많은 WeChat 알림이 루프에 푸시되어 스레드 차단이 발생했습니다. 이 문제는 비즈니스 주문량이 일정량 이상 증가한 후에만 나타나므로 매우 숨겨져 있습니다. 불행하게도 어제 발발했습니다. 알아내는 방법은 무엇입니까? 단서를 얻으려면 시스템의 푸시 로그를 확인해야 합니다. 한 계정은 동시에 거의 3억 번 푸시했습니다! ! ! 후자의 조사 결과 B측 구현 엔지니어가 우리를 위해 개발한 일반 WeChat 푸시 클래스로 인해 발생한 것으로 밝혀졌습니다.

다음은 오류 코드입니다(예비 분류: 해당 업체가 폐쇄 루프 제어를 수행하지 않고 무한 루프가 발생하여 시스템 정체를 유발함).

/**
    	 * 二开公司负责插件,运行逻辑出现功能性阻塞,
    	 * 原因:初步分析,迭代出现阶乘处理,也没有做闭环控制,导致类死循环出现,系统崩溃
    	 * 解决方案:该插件注释停用,不予运行
    	 */
        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亿次
        }

원칙은 간단하지만 그 결과는 은폐되고 심각합니다.Kingdee 본부 교사들이 조심스럽고 책임감을 갖지 않으면 시스템이 정말 무너질 것입니다!

처리 결과: 플러그인을 비활성화하고 주석 처리합니다.

Supongo que te gusta

Origin blog.csdn.net/lijinquan2009/article/details/124452189
Recomendado
Clasificación