CommandLineRunner 可能会导致你的应用宕机停止,我劝你耗子尾汁
hello,大家好,我是小黑,又和大家见面啦~~
如果你去某度搜索关键词 CommandLineRunner 初始化资源
,截止小黑同学写这篇推文之前,大概能收到 1,030,000
个结果。
网上大部分的文章都在告诉我们说可以使用 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");
}
}
运行日志如下:
可以看到,Spring 容器一开始正常运行,系统开始对外提供服务。一分钟之后,CommandLineRunner
在执行过程中报错,导致 Spring 容器关闭,应用停止服务。
再多说几句
虽然上文中这些案例都很简单,但小黑同学在实际过程中,还真就遇到过有同学使用 CommandLineRunner
去初始化了一个很耗时的资源,而在初始化资源的时候,又不小心报错了,于是应用就突然停止了。不过幸运的是,这次只是发生在了测试环境,线上一切正常。