测试环境: Spring Boot MVC + RabbitMQ + Task + Tomcat

Controller层

测试代码

 @RequestMapping("/world")
    @ResponseBody
    public String hello() throws InterruptedException {
        System.out.println("in controller");
        for(int i=0; i<100000000; i++){
            System.out.println("in " + i + " hehe");
        }
        System.out.println("out controller");
        return "OK.";
    }

关闭方式:

shutdown

curl -X POST http://localhost:8080/shutdown

没有执行到out controller程序就退出了

kill

jps -vm | grep Demo | awk '{print $1}' | xargs kill

没有执行到out controller程序就退出了

Task

测试代码

    @Scheduled(fixedRate = 1000 * 10)
    public void run() throws InterruptedException {
        System.out.println("in task before " + Thread.currentThread().getName());
        for (int i = 0; i < 10000000; i++) {
            System.out.println("in " + i + " task");
        }
        System.out.println("out task ok " + Thread.currentThread().getName());
    }

关闭方式:

shutdown

curl -X POST http://localhost:8080/shutdown

它会等待线程执行完毕程序再退出,即执行到了”out task ok xxx”

kill

jps -vm | grep Demo | awk '{print $1}' | xargs kill

没有执行到out task ok xxx程序就退出了

listener 层

测试代码

    @RabbitListener(queues = "test.queue")
    public void run() {
        System.out.println("in listener");
        for (int i = 0; i < 10000000; i++) {
            System.out.println("in " + i + " listener");
        }
        System.out.println("out listener");
    }

关闭方式:

shutdown

curl -X POST http://localhost:8080/shutdown

程序会等等执行完毕再退出,即执行到了out listener

kill

jps -vm | grep Demo | awk '{print $1}' | xargs kill

没有执行到out listener程序就退出了

结论

最好停止Tomcat的方式是: 通过Nginx加负载均衡,在Nginx上停用某个Tomcat的连接(upstream),然后过一段时间后,再调用Tomcat的shutdown.sh,以尽可能减少数据的丢失。 其他的方式来停止Tomcat,都会有风险。