zoukankan      html  css  js  c++  java
  • 记一次手贱导致的线上事故

    事情是这样的。。

    ​ 写业务,测试,测的过程很漫长。。不细说了。

    ​ 终于测完了,有点飘,手贱的把代码合并到了主分支,恰好一个小时后有其他同事上线功能,本来他是要上他的功能,结果他的代码没有CR就没合并,所以主分支上只有我的代码。然后我的代码就被误上了。不过就算他不上线功能,总还是有可能其他人上线功能。。。

    ​ 由于我的代码属于下游功能,有上游,上游没合代码,只有我的合了还上线了,我的上游的调用方式是异步,这个旧版异步代码会吞异常,所以就没捕获住异常。。线上功能不正常就导致报警了。。。

    代码模拟

    public class MainThread {
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            //normal......
            // 模拟异步调用,jdk的框架要求你显式抛出或捕获异常。。。
            final ExecutorService pool = Executors.newSingleThreadExecutor();
            final Future<Integer> future = pool.submit(new AsyncCall());
            System.out.println(future.get());
            System.out.println("over");
        }
        private static class AsyncCall implements Callable<Integer> {
    
            @Override
            public Integer call() throws Exception {
                System.out.println(1/0);
                return 1;
            }
        }
    }
    

    结果是

    Exception in thread "main" java.util.concurrent.ExecutionException: java.lang.ArithmeticException: / by zero
    	at java.util.concurrent.FutureTask.report(FutureTask.java:122)
    	at java.util.concurrent.FutureTask.get(FutureTask.java:192)
    	at com.线上事故复盘.异步调用内部异常.MainThread.main(MainThread.java:16)
    Caused by: java.lang.ArithmeticException: / by zero
    	at com.线上事故复盘.异步调用内部异常.MainThread$AsyncCall.call(MainThread.java:23)
    	at com.线上事故复盘.异步调用内部异常.MainThread$AsyncCall.call(MainThread.java:19)
    	at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    	at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    	at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    	at java.lang.Thread.run(Thread.java:748)
    
    

    这样over就没有执行,导致后续业务不能正常执行。。。

    做一点修改

    public class MainThread {
        public static void main(String[] args) throws ExecutionException, InterruptedException {
            //normal......
            // 模拟异步调用
            final ExecutorService pool = Executors.newSingleThreadExecutor();
            final Future<Integer> future = pool.submit(new AsyncCall());
            try {
                System.out.println(future.get());
            } catch (InterruptedException | ExecutionException e) {
                e.printStackTrace();
            }
            System.out.println("over");
        }
        private static class AsyncCall implements Callable<Integer> {
    
            @Override
            public Integer call() throws Exception {
                System.out.println(1/0);
                return 1;
            }
        }
    }
    
    

    没别的,就是catch一下。

    事故总结

    • 别随便把代码合到主分支!!!一定要从全局去考虑你的代码。

    • 合代码一定要找自己的负责人CR,别人不清楚你的功能。

    • 公司内部封装的异步调用一定要看一下内部实现,看看有没有catch,没有catch就在外部catch,防止异步调用的失败影响到后面的流程

  • 相关阅读:
    Java经典逻辑编程50题 (转)
    Programmingbydoing
    前端测试框架jest 简介
    puppeteer入门
    面向对象编程
    Java常识
    JS 变量
    jmeter 压力测试
    jmeter 安装
    Java 数据驱动测试
  • 原文地址:https://www.cnblogs.com/woooodlin/p/13991807.html
Copyright © 2011-2022 走看看