CommandLineRunner 可能會導致你的應用當機停止,我勸你耗子尾汁

Coder小黑發表於2020-12-08

hello,大家好,我是小黑,又和大家見面啦~~

如果你去某度搜尋關鍵詞 CommandLineRunner 初始化資源 ,截止小黑同學寫這篇推文之前,大概能收到 1,030,000 個結果。

CommandLineRunner 初始化資源

網上大部分的文章都在告訴我們說可以使用 CommandLineRunner 去初始化資源,但幾乎很少有文章告訴我們:如果 CommandLineRunner 使用不當,就會導致程式出現一些奇怪的異常,更有可能導致我們的應用直接停止執行

正在讀這篇文章的你如果也使用了 CommandLineRunner 去初始化資源,那麼小黑同學勸你耗子尾汁,趕緊來看一下下面這些案例吧~

CommandLineRunner 執行時間太久了???

@Slf4j
@SpringBootApplication
public class CommandLineRunnerDemoApp {

    private Map<String, String> map;

    public static void main(String[] args) {
        SpringApplication.run(CommandLineRunnerDemoApp.class, args);
    }
    
    @RestController
    public class controller {

        @GetMapping("/name")
        public String name() {
            return map.get("name");
        }
    }

    @Bean
    public CommandLineRunner commandLineRunner() {
        return args -> {
            // 模擬載入資料過慢
            log.info("start do commandLineRunner...");
            TimeUnit.MINUTES.sleep(1);
            map = ImmutableMap.of("namne", "coder小黑");
            log.info("do commandLineRunner end");
        };
    }
}

Spring 容器啟動之後,訪問 http://localhost:8080/name,此時後臺就會直接報錯:

報錯日誌

通過報錯資訊我們可以知道:

CommandLineRunner 在 Spring 容器起來之後開始執行,但此時 Tomcat 已經可以正常接收請求。又由於本案例中 CommandLineRunner 的執行時間過長,資料還沒有初始化完成,於是程式就開始出錯了......

CommandLineRunner 執行報錯了 ???

那如果 CommandLineRunner 在執行過程中報錯了會怎麼樣呢?

答案是:Spring 容器會自動關閉,應用會停止服務。

可能讀者會反駁小黑同學說:“CommandLineRunner 在啟動時執行,如果 CommandLineRunner 執行報錯,那就釋出失敗唄。”

其實還有更嚴重的......

當執行時間過長遇上報錯,你的應用還好嗎???

廢話不多說,直接上具體案例,先看程式碼:

@Slf4j
@SpringBootApplication
public class CommandLineRunnerDemoApp2 implements CommandLineRunner {

    public static void main(String[] args) {
        SpringApplication.run(CommandLineRunnerDemoApp2.class, args);
    }

    @Override
    public void run(String... args) throws Exception {
        log.info("start do commandLineRunner...");
        // 模擬任務執行時長
        TimeUnit.MINUTES.sleep(1);

        // 模擬執行過程中出錯
        int i = 1 / 0;

        log.info("do commandLineRunner end");
    }
}

執行日誌如下:

報錯日誌2

可以看到,Spring 容器一開始正常執行,系統開始對外提供服務。一分鐘之後,CommandLineRunner 在執行過程中報錯,導致 Spring 容器關閉,應用停止服務。

再多說幾句

雖然上文中這些案例都很簡單,但小黑同學在實際過程中,還真就遇到過有同學使用 CommandLineRunner 去初始化了一個很耗時的資源,而在初始化資源的時候,又不小心報錯了,於是應用就突然停止了。不過幸運的是,這次只是發生在了測試環境,線上一切正常。

相關文章