SpringBoot项目优雅停机+Pid暴力停机

springboot,项目,优雅,停机,pid,暴力 · 浏览次数 : 16

小编点评

## Spring Boot 项目优雅停机的配置 **bootstrap.yaml 中的 pid 属性配置了 Spring Boot 项目的 PID 输出位置,默认情况下它会将 PID 写入 `application.pid` 文件中。** **以下是配置的各个部分:** * **`spring: pid: file: F:/cloud-nacos/cloud_gateway/application.pid`**: * `spring` 是一个配置类,用于配置 Spring Boot 项目。 * `pid` 是一个属性,用于指定 PID 输出位置。 * `file` 是属性的值,它指定 PID 文件的路径。 * `F:/cloud-nacos/cloud_gateway/application.pid` 是文件路径的绝对路径。 * **`@SpringBootApplication`**: * `@SpringBootApplication` 注解用于配置 Spring Boot 项目。 * `@EnableDiscoveryClient` 是一个配置类,用于配置 Spring Cloud Discovery 服务。 * **`@RestController`**: * `@RestController` 注解用于标记当前类是一个 REST 控制器。 * `@Slf4j` 是一个日志记录类,用于记录日志信息。 * **`@GetMapping(value = {"/ShutDown", "/shutdown"})`**: * `@GetMapping` 注解用于定义一个 API endpoint,处理优雅停机请求。 * `value` 参数用于指定 API 路径。 * `"/ShutDown"` 和 `"/shutdown"` 是优雅停机的请求路径。 * **`@GetMapping(value = {"/queryPid", "/getPid"})`**: * `@GetMapping` 注解用于定义一个 API endpoint,用于获取应用程序的 PID。 * `value` 参数用于指定 API 路径。 * `"/queryPid"` 和 `"/getPid"` 是获取 PID 的请求路径。 * **`@GetMapping(value = {"/kill", "/stop", "/termination"})`**: * `@GetMapping` 注解用于定义一个 API endpoint,用于处理强制停止请求。 * `value` 参数用于指定 API 路径。 * `"/kill"`、`"/stop"` 和 `"/termination"` 是强制停止的操作路径。 * **`@PreDestroy`**: * `@PreDestroy` 注解用于定义一个生命周期方法,在项目关闭时执行清理操作。 * `PreDestroy` 方法中定义了 `exitApplication()` 方法,用于优雅关闭应用程序。 * **`private String getPidFunction()`**: * `getPidFunction()` 方法用于获取应用程序的 PID。 * 它首先从环境变量 `spring.pid.file` 中获取 PID 文件路径。 * 如果 PID 文件不存在,它会从 `application.pid` 文件中获取。 **总结:** 该配置定义了优雅停机和强制停止 API 端点,并确保在程序正常关闭时执行清理操作。

正文

bootstrap.yaml配置项目的pid输出位置

spring:
  pid:
    file: F:/cloud-nacos/cloud_gateway/application.pid

springboot项目修改启动类启动方式

原始启动类
SpringApplication.run(MainApplication.class, args);

@SpringBootApplication
@EnableDiscoveryClient
public class GateWayApp {
    /**
     * @author: GuoTong
     * @date: 2022-10-05 10:42:59
     */
    public static void main(String[] args) {
        try {
            System.setProperty("spring.devtools.restart.enabled", "false");
            SpringApplication springApplication = new SpringApplication(MainApplication.class);
            springApplication.addListeners(new ApplicationPidFileWriter());
            springApplication.run(args);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

优雅停机和暴力停机的接口

package com.gton.shutdown;

import com.alibaba.cloud.commons.io.FileUtils;
import com.alibaba.cloud.commons.lang.StringUtils;
import com.gton.config.Resp;
import io.netty.util.CharsetUtil;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeansException;
import org.springframework.boot.ExitCodeGenerator;
import org.springframework.boot.SpringApplication;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.core.env.Environment;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.PreDestroy;
import java.io.File;
import java.io.IOException;

/**
 * @description: 优雅停机?
 * 简单的说,就是向应用进程发出停止指令之后,能保证正在执行的业务操作不受影响,
 * 直到操作运行完毕之后再停止服务。
 * @author: GuoTong
 * @createTime: 2023-07-14 22:32
 * @since JDK 1.8 OR 11
 **/
@RestController
@Slf4j
public class ApplicationContextShutDown implements ApplicationContextAware {

    private ApplicationContext context;


    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        this.context = applicationContext;
    }

    /**
     * Description: 优雅停机
     *
     * @author: GuoTong
     * @date: 2023-07-14 22:46:01
     * @return:void
     */
    @GetMapping(value = {"/ShutDown", "/shutdown"})
    public void shutdownFunction() {
        log.info("Application Context  Doing ShutDown  .......");
        ((ConfigurableApplicationContext) context).close();
    }

    /**
     * Description: 获取进程号
     *
     * @author: GuoTong
     * @date: 2023-07-14 22:46:01
     * @return:void
     */
    @GetMapping(value = {"/queryPid", "/getPid"})
    public Resp queryApplicationPid() {
        String fileInputStreamPid = getPidFunction();
        return Resp.Ok(fileInputStreamPid);
    }


    /**
     * Description: 强行终止进程
     *
     * @author: GuoTong
     * @date: 2023-07-14 22:46:01
     * @return:void
     */
    @GetMapping(value = {"/kill", "/stop", "/termination"})
    public void termination() {
        // 获取上下文环境信息{application.yml}
        String pid = getPidFunction();
        String endingApplicationShell = "kill -9 " + pid;
        // java主要通过Runtime和Process执行Linux命令, Process是Runtime.exec返回值,可以用来对执行过程进行后续操作(获取结果,发送命令,等待结果)。
        try {
            log.info("强行终止进程 ,{}", endingApplicationShell);
            Runtime.getRuntime().exec(endingApplicationShell);
        } catch (IOException e) {
            log.error("强行终止进程失败", e);
        }
    }

    /**
     * Description:  容器销毁前调用
     *
     * @author: GuoTong
     * @date: 2023-07-14 22:42:19
     * @return:
     */
    @PreDestroy
    public void PreDestroy() {
        log.info("springBoot项目已经优雅关闭  .......");
    }

    /**
     * Description:Springboot自身提供的优雅停机
     *
     * @param applicationContext
     * @author: GuoTong
     * @date: 2023-07-14 22:42:08
     * @return:
     */
    public void exitApplication(ApplicationContext applicationContext) {
        // SpringApplication.exit()方法也可以安全的退出程序
        int exit = SpringApplication.exit(applicationContext, (ExitCodeGenerator) () -> 0);
        //同时会返回一个退出码,这个退出码可以传递给所有的context最后通过调用System.exit()可以将这个错误码也传给JVM。
        System.exit(exit);
    }

    /**
     * Description:  获取上下文环境信息{application.yml}PID
     *
     * @author: GuoTong
     * @date: 2023-07-15 00:15:14
     * @return:java.lang.String
     */
    private String getPidFunction() {
        Environment environment = context.getEnvironment();
        String pidFileName = environment.getProperty("spring.pid.file");
        if (StringUtils.isEmpty(pidFileName)) {
            pidFileName = "application.pid";
        }
        String fileInputStreamPid = null;
        try {
            fileInputStreamPid = FileUtils.readFileToString(new File(pidFileName), CharsetUtil.UTF_8);
        } catch (IOException e) {
            log.info("获取Pid失败", e);
        }
        return fileInputStreamPid;
    }

}

与SpringBoot项目优雅停机+Pid暴力停机相似的内容:

SpringBoot项目优雅停机+Pid暴力停机

# bootstrap.yaml配置项目的pid输出位置 ```yaml spring: pid: file: F:/cloud-nacos/cloud_gateway/application.pid ``` # springboot项目修改启动类启动方式 > 原始启动类 SpringApplica

SpringBoot项目添加2FA双因素身份认证

什么是 2FA(双因素身份验证)? 双因素身份验证(2FA)是一种安全系统,要求用户提供两种不同的身份验证方式才能访问某个系统或服务。国内普遍做短信验证码这种的用的比较少,不过在国外的网站中使用双因素身份验证的还是很多的。用户通过使用验证器扫描二维码,就能在app上获取登录的动态口令,进一步加强了账

SpringBoot项目实现日志打印SQL明细(包括SQL语句和参数)几种方式

前言 我们在开发项目的时候,都会连接数据库。有时候遇到问题需要根据我们编写的SQL进行分析,但如果不进行一些开发或者配置的话,这些SQL是不会打印到控制台的,它们默认是隐藏的。下面给大家介绍几种常用的方法。 第一种、代码形式 Mybatis框架是Java程序员最常用的数据库映射框架,MyBatis

Springboot项目使用Undertow替换内置Tomcat服务器,实现RESTFUL接口web应用

Maven实例:pom.xml文件中添加更换依赖 org.springframework.boot spring-boot-starter

[转帖]SpringBoot项目banner.txt生成教程

文章目录 近期在做毕业设计,后端框架用到了SpringBoot,可以自己个性化设置banner.txt 地址:https://www.bootschool.net/ascii 可以直接下载,然后直接将banner.txt放到resource目录下 如果想要显示SpringBoot版本等信息,可以添加

SpringBoot项目从0到1配置logback日志打印

大家好!我是sum墨,一个一线的底层码农,平时喜欢研究和思考一些技术相关的问题并整理成文,限于本人水平,如果文章和代码有表述不当之处,还请不吝赐教。 以下是正文! 一、写文背景 我们在写后端项目的时候,日志打印是必需的。支持SpringBoot项目的日志框架一般有log4j、logback,这二者各

利用SpringBoot项目做一个Mock挡板;基于事件发布动态自定义URL和响应报文

# 导入SpringbootWEb依赖 ```xml org.springframework.boot spring-boot-starter-web ${spring-boot-start-version} org.springframework.boot spring-boot-starter-

Vue+SpringBoot项目分离部署踩坑记录

编程经验总结

windows下使用dockerdesktop进行部署

Docker部署springboot项目 环境准备 要在windows上使用docker需要确认系统的需求 需要启用虚拟化支持的CPU 启用适用于windows的Linux子系统功能 保证足够的内存 下载dockerdesktop 下载后会提示安装对应的环境 坑点 安装过程中需要安装wsl环境,会遇

安装docker并部署java项目

docker部署springboot项目(详细教程)_使用docker部署springboot项目_流星007的博客-CSDN博客 ps:以下是部署到linux 服务器中的 案例(与chatgpt的对话内容) 确保Dockerfile文件名正确: 您在命令中提到了创建名为"dockerfile"的文