美文网首页
StringBoot如何进行优雅停机

StringBoot如何进行优雅停机

作者: 风静花犹落 | 来源:发表于2022-05-13 12:51 被阅读0次

强制停机

无论是Linux的Kill -9 pid还是windows的taskkill /f /pid强制关闭进程,都会带来一些副作用,如:

  1. 请求丢失:内存队列中等待执行的请求丢失;

  2. 数据丢失:处于内存中的数据尚未持久化到磁盘中;

  3. 业务中断:处理一半的业务被强行中断,却没有更新到数据库中;

  4. 文件损坏:正在进行文件的write操作中,突然退出,导致文件损坏;

  5. 锁表:在操作数据库多表更新时,事务方法执行中断,导致数据库锁表;

优雅停机

Java是通过 JDK 的 ShutdownHook 来完成优雅停机的,当程序接收到退出指令后,会标记为退出状态,此时不再接收新的消息,然后将积压的消息处理完后回收资源,最后关闭线程。所以不能直接使用kill -9 PID 等强制关闭指令,只有通过 kill -2 PID(Ctrl + C)kill PID (kill -15 PID)时,才会通知程序调用ShutdownHook方法。通常优雅停机需要有等待超时机制,如果在规定时间内还未完成退出前的操作,则由直接调用kill -9 PID,强制退出。

ShutdownHook用法
Runtime.getRuntime().addShutdownHook(new Thread(() -> {
    System.out.println("关闭应用,释放资源");
}));
优雅停机脚本stop.sh
#!/bin/bash

cd `dirname $0`

SERVER_PORT=$1

if [ ! -n "$SERVER_PORT" ]; then
  echo "用法:$0 <SERVER_PORT>"
  exit 1
fi

PIDS=`ps aux | grep java | grep "--server.port=$SERVER_PORT" | awk '{print $2}'`

if [ -z "$PIDS" ]; then
    echo "错误: 指定端口的服务进程没有运行!"
    exit 1
fi

echo -e "正在停止 ...\c"
for PID in $PIDS ; do
    kill $PID > /dev/null 2>&1
done

COUNT=0
NUM=0
#等待程序处理积压的消息
while [ $COUNT -lt 1 ]; do    
    echo -e ".\c"
    sleep 1
    NUM=$(( $NUM + 1 ))

    COUNT=1
    for PID in $PIDS ; do
        PID_EXIST=`ps -f -p $PID | grep java`
        if [ -n "$PID_EXIST" ]; then
            COUNT=0
            break
        fi
    done

    #90秒超时强制退出
    if [ $NUM -gt 90 ]; then
        for PID in $PIDS ; do
           kill -9 $PID > /dev/null 2>&1
        done
        break
    fi
done

echo "成功关闭进程: $PIDS"

StringBoot配置

spring boot 2.3.x 版本以后,内置了优雅停机的机制,也就不需要自行扩展容器的线程池来处理, 目前spring boot嵌入式支持的web服务器(Jetty、Reactor Netty、Tomcat 和 Undertow)以及反应式和基于Servlet的web 应用程序都支持优雅停机功能。只需在application.yml中添加如下配置即可。

server:
  shutdown: graceful  #关停方式,默认IMMEDIATE(立即关闭)

spring:
  lifecycle:
    timeout-per-shutdown-phase: 30s #最大等待线程结束时间,默认30s

容器表现行为

Web 容器 表现行为
Tomcat 9.0.33+ 停止接收请求,客户端新请求等待超时。
Reactor Netty 停止接收请求,客户端新请求等待超时。
Undertow 停止接收请求,客户端新请求直接返回 503。

相关文章

  • StringBoot如何进行优雅停机

    强制停机 无论是Linux的Kill -9 pid还是windows的taskkill /f /pid强制关闭进程...

  • Dubbo在Docker中的优雅停机

    Dubbo在Docker中的优雅停机 优雅停机 优雅停机是指在停止应用时,执行的一系列保证应用正常关闭的操作。这些...

  • SpringCloud微服务如何优雅停机及源码分析

    [SpringCloud微服务如何优雅停机及源码分析] ( 原文链接:https://www.cnblogs.co...

  • Dubbo ShutdownHook 优雅停机整理

    Dubbo优雅停机的机制 Dubbo是通过JDK的ShutdownHook来完成优雅停机的所以如果用户使用 kil...

  • 如何优雅的不停机,无损进行海量数据迁移?

    作者:看松 背景 在系统的快速迭代过程中,业务系统往往部署在同一个物理库,没有做核心数据和非核心数据的物理隔离。随...

  • dubbo - 优雅停机

    开篇 这篇文章主要的目的是想分析下dubbo优雅停机的过程,整个文章参考网上很多现成的文章,本着尊重原创的精神会在...

  • dubbo优雅停机

    1 概要说明 我们在关闭或重启dubbo服务时往往会出现请求超时而导致pv lost。 2 原因分析 关闭dubb...

  • Dubbo 优雅停机

    之前的几个章节都在讲解Dubbo的种种流程性的逻辑,首先讲到了服务启动和服务调用,然后又讲到了服务治理的一些内容。...

  • Dubbo优雅停机

    简介 Dubbo 是通过 JDK 的 ShutdownHook 来完成优雅停机的,所以如果用户使用 kill -9...

  • Dubbo 优雅停机

    优雅停机特性是所有 RPC 框架中非常重要的特性之一,因为核心业务在服务器中正在执行时突然中断可能会出现严重后果,...

网友评论

      本文标题:StringBoot如何进行优雅停机

      本文链接:https://www.haomeiwen.com/subject/pdnyurtx.html