在Quarkus中如何在关闭信号后接受http请求?信号、如何在、Quarkus、http

2023-09-03 14:20:09 作者:不惑的年代

我尝试过:

void onShutdown(@Observes final ShutdownEvent event) throws InterruptedException {
    log.infof("ShutdownEvent received, waiting for %s seconds before shutting down", shutdownWaitSeconds);
    TimeUnit.SECONDS.sleep(shutdownWaitSeconds);
    log.info("Continue shutting down");
}
但在收到ShutdownEvent后,Quarkus已经用503响应http请求。看起来这可以通过preShutdown中的ShutdownListener方法来完成。我已经实现了这个侦听器,但它还没有被调用。如何注册ShutdownListener

此处的使用案例是OpenShift向终止Pod发送请求。

Quarkus

iPhone 12的信号依旧很差 来试试这几种方法

选项1:创建推荐答案扩展

说明为here。ShutdownController是我自己的类实现ShutdownListener,其中我在preShutdown方法中休眠。

class ShutdownControllerProcessor {

    @BuildStep
    FeatureBuildItem feature() {
        return new FeatureBuildItem("shutdown-controller");
    }

    @BuildStep
    ShutdownListenerBuildItem shutdownListener() {
        // Called at build time. Default constructor will be called at runtime.
        // Getting MethodNotFoundException when calling default constructor here.
        return new ShutdownListenerBuildItem(new ShutdownController(10));
    }
}

选项2:修改Shutdown Recorder私有静态最终字段

可以使用反射添加新的关机监听程序。这是一个有点难看的解决方案。

registerIfNeeded()需要在Quarkus启动后调用,例如,计时器在@PostConstruct之后1秒。

@ApplicationScoped
public class ListenerRegisterer {

    public void registerIfNeeded() {
        try {
            tryToRegister();
        } catch (NoSuchFieldException | IllegalAccessException e) {
            throw new IllegalStateException(e);
        }
    }

    private void tryToRegister() throws NoSuchFieldException, IllegalAccessException {
        final var field = ShutdownRecorder.class.getDeclaredField("shutdownListeners");
        field.setAccessible(true);
        final var listeners = (List<ShutdownListener>) field.get(null);
        if (listeners != null && !listeners.toString().contains("ShutdownController")) {
            listeners.add(new ShutdownController(10));
            setFinalStatic(field, listeners);
        }
    }

    private static void setFinalStatic(final Field field, final Object newValue) throws NoSuchFieldException, IllegalAccessException {
        field.setAccessible(true);
        final var modifiersField = Field.class.getDeclaredField("modifiers");
        modifiersField.setAccessible(true);
        modifiersField.setInt(field, field.getModifiers() & ~Modifier.FINAL);
        field.set(null, newValue);
    }

}