Java 如何记录WELD SE容器关闭的原因
编辑:原来我的docker容器正在关闭,因为错误的健康检查失败。这导致kubernetes探测器多次失败,导致吊舱死亡。由于该命令来自JVM外部,因此代码可能无法知道JVM周围的容器何时被终止。把这个问题留着,以防有人找到答案 我有一个JavaSE项目,它读入参数来处理文件。我使用焊接SE进行注射。运行几分钟后,焊接容器停止运行,无需解释。下面是我的代码框架。这是我的主课Java 如何记录WELD SE容器关闭的原因,java,weld-se,Java,Weld Se,编辑:原来我的docker容器正在关闭,因为错误的健康检查失败。这导致kubernetes探测器多次失败,导致吊舱死亡。由于该命令来自JVM外部,因此代码可能无法知道JVM周围的容器何时被终止。把这个问题留着,以防有人找到答案 我有一个JavaSE项目,它读入参数来处理文件。我使用焊接SE进行注射。运行几分钟后,焊接容器停止运行,无需解释。下面是我的代码框架。这是我的主课 @ApplicationScoped public class Main { @Setter //Lombok ann
@ApplicationScoped
public class Main {
@Setter //Lombok annotation
private Scheduler scheduler;
public void schedule(String[] filenames) throws InterruptedException {
scheduler.schedule(filenames);
}
@PreDestroy
public void cleanUp() {
log.info("PreDestroy - Main");
//clean up omitted
}
public static void main(String[] args) {
Weld weld = new Weld();
Main main = null;
try (WeldContainer container = weld.initialize()) {
main = container.select(Main.class).get();
Scheduler scheduler = CDI.current().select(Scheduler.class).get();
main.setScheduler(scheduler);
main.schedule(args);
log.info("Main - completed processing");
} catch (Exception e) {
log.info("Exception occurred: " + e.getMessage(), e);
} finally {
log.info("Main Finally - Shutting down Weld");
CDI.current().destroy(main);
weld.shutdown();
}
}
}
这是我的调度程序类
@Named
public class Scheduler {
private ThreadPoolExecutor executor;
private Map<Future<?>, Importer> beanMap = new HashMap<>();
private static final Duration sleepDuration = Duration.ofSeconds(45);
@PostConstructor
public void init() {
//setup executor
}
@PreDestroy
public void cleanUp() {
log.info("PreDestroy - Scheduler");
//clean up omitted
}
public void schedule(String[] filenames) throws InterruptedException {
for(String filename : filenames) {
Importer caller = CDI.current().select(Importer.class).get();
caller.setFilename(filename);
Future<?> future = executor.submit(caller);
beanMap.put(future, caller);
}
while(!isDone()) {
Thread.sleep(sleepDuration.toMillis());
log.info("Remaining threads: {}, getRemaining());
destroyCompleted();
}
}
//Returns true only when all threads are completed
private boolean isDone() { //code omitted }
//Returns number of not completed threads
private int getRemaining() { //code omitted }
//Clean up any completed Importers
private boolean destroyCompleted() { //code omitted }
}
我正在调试级别记录“org.jboss”。我可以看到容器在处理文件的中途被关闭,但我不明白为什么会发生这种情况。是否有某种类型的侦听器可以扩展/实现,以了解为什么会发生关闭命令?供将来参考:您可以为事件定义一个观察者方法,至少可以在关闭之前关闭所有打开的文件等。它不一定会给你一个关闭的理由,但这是一个开始 如果您说JVM进程是从外部终止的,那么可能有一个InterruptedException抛出到您可以捕获的地方。请注意,捕获InterruptedException而不重新中断线程在大多数情况下都是一个bug。在您的情况下,在调用线程“睡眠”时,您应该有秩序地关闭它。如果线程被中断,则有人希望取消执行。他们这样做可能有很好的理由;别以为你比他们知道得多
至少您可以在执行过程中的某个方便点定期检查线程的中断标志,以启动有序的任务关闭。在您回复之前,我忘记了这个问题。原来是有人修改了舵图,修改了kubernetes的健康检查。我更新了配置文件以更正此问题。我还没有时间回去看看这个建议是否有效。
@Named
public class Importer implements Callable<String> {
@Setter //lombok annotation
private String filename;
public void cleanUp() {
log.info("PreDestroy - Importer");
//clean up omitted
}
public String call() {
List<String> content = //extract file content
for(int i = 0; i < content.size; i++) {
if (i+1 % 10000 == 0) {
log.info("Processed {} rows in file {}", i+1, filename);
}
//rest of loop omitted
}
}
}
Processed 50000 rows in file test.txt
Processed 60000 rows in file text.txt
PreDestroy - Scheduler
PreDestroy - Importer
PreDestroy - Main
WELD-ENV-002001: Weld SE container 03128098-039d-46db-97e5-8538a52a38cc shut down