Elastic Beanstalk - 正常关闭时间太短

mic*_*cah 7 java amazon-web-services amazon-elastic-beanstalk

我正在尝试在弹性 beanstalk 应用程序上实现正常关闭,并且我已经整理了此关闭测试 -

主要的-

public class Main {

    public static void main(String[] args) throws InterruptedException {
        ShutdownTest shutdownTest = new ShutdownTest();
        shutdownTest.run();

        System.out.println("END OF MAIN");
    }
}
Run Code Online (Sandbox Code Playgroud)

测试班-

import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class ShutdownTest {

    private volatile long jobEnd;
    private volatile boolean shutdown = false;

    public void run() throws InterruptedException {

        Thread mainThread = Thread.currentThread();

        Thread shutdownHook = new Thread(() -> {
            runShutdownTimer();

            try {
                System.out.println("Got shutdown signal.");

                shutdown = true;

                mainThread.join();
            } catch(Exception e) {
                System.out.println(e);
            }
        });

        Runtime.getRuntime().addShutdownHook(shutdownHook);

        while(!shutdown) {
            long jobStart = System.currentTimeMillis();
            int jobRunTime = 60000;
            jobEnd = jobStart + jobRunTime;
            Thread.sleep(jobRunTime);
        }


        System.out.println("End of Run");
    }

    public void runShutdownTimer() {
        long start = System.currentTimeMillis();
        float waitTime = (jobEnd - start)/1000f;

        System.out.println("Shutdown phase should take " + waitTime + " seconds");

        ExecutorService executorService = Executors.newFixedThreadPool(1);
        executorService.execute(() -> {
            while(true) {
                long now = System.currentTimeMillis();
                float diff = (float)(now - start)/1000f;

                System.out.println(diff + " seconds elapsed in shutdown phase");

                try {
                    Thread.sleep(300);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        });
    }
}
Run Code Online (Sandbox Code Playgroud)

如果我在本地运行它并发送关闭信号(^C 或通过我的 IDE 停止执行),我将得到如下输出:

Shutdown phase should take 45.139 seconds
Got shutdown signal.
0.006 seconds elapsed in shutdown phase
0.311 seconds elapsed in shutdown phase
0.615 seconds elapsed in shutdown phase
...
44.433 seconds elapsed in shutdown phase
44.734 seconds elapsed in shutdown phase
45.035 seconds elapsed in shutdown phase
End of Run
END OF MAIN
<END OF EXECUTION>
Run Code Online (Sandbox Code Playgroud)

但如果我在 Elastic Beanstalk 上运行它并通过推送新版本发送关闭信号,我会得到类似这样的信息 -

Shutdown phase should take 25.647 seconds
Got shutdown signal.
0.007 seconds elapsed in shutdown phase
0.307 seconds elapsed in shutdown phase
0.607 seconds elapsed in shutdown phase
...
9.614 seconds elapsed in shutdown phase
9.915 seconds elapsed in shutdown phase
10.215 seconds elapsed in shutdown phase
<END OF EXECUTION>
Run Code Online (Sandbox Code Playgroud)

我已经这样做过几次了,看起来执行会在 10 秒左右强制退出,无论它应该等待多少时间。这些应用程序运行的作业可能需要超过 10 秒的时间,这取决于不可控的外部力量的网络和请求速度。

有没有办法增加强制终止超时?

编辑:

我尝试通过 ssh 进入盒子并终止进程pkill java(没有信号)。日志显示应用程序成功完成了 28 秒的关闭过程。正如我怀疑的那样,有关弹性 beanstalk 服务的某些内容正在发出第二个 sigterm。当我弄清楚它是什么时我会更新。

编辑编辑:

我研究了 ASG 生命周期挂钩。它们通过在终止事件开始时发出 cloudwatch 事件来工作。此事件包含 ec2 实例 ID,并且可以由 SNS 主题发送到/路由。当 ASG 生命周期挂钩配置为发出此类事件时,它将等待确认终止可以在可配置的超时期限内继续。这意味着 ASG 中的每个 EC2 都可以侦听该 SNS 主题以了解其自己的终止事件,启动关闭过程,然后提醒 ASG 终止过程可以继续。

这可能适用于扩展,但在更新 EC2 环境时不起作用 - 导致应用程序重新启动。