python 程序停止打印日志_停止 Spring Boot 服务的几种优雅姿势

ce0305d324a4fa5f892634057416599b.png

在使用 Spring Boot 的时候,都要涉及到服务的停止和启动,当我们停止服务的时候,很多时候大家都是 kill -9 直接把程序进程杀掉,这样程序不会执行优雅的关闭。而且一些没有执行完的程序就会直接退出。

我们很多时候都需要安全的将服务停止,也就是把没有处理完的工作继续处理完成。比如停止一些依赖的服务,输出一些日志,发一些信号给其他的应用系统,这个在保证系统的高可用是非常有必要的。那么咱么就来看一下几种停止 Spring Boot 的方法。

第一种就是 Spring Boot 提供的 actuator 的功能,它可以执行 shutdown, health, info 等,默认情况下,actuator 的 shutdown 是 disable 的,我们需要打开它,首先引入 acturator 的 maven 依赖。

  <dependency>

<groupId>org.springframework.bootgroupId>

<artifactId>spring-boot-starter-actuatorartifactId>

dependency>

然后将 shutdown 节点打开,也将 /actuator/shutdown 暴露 web 访问也设置上,除了 shutdown 之外还有 health, info 的 web 访问都打开的话将 management.endpoints.web.exposure.include=* 就可以。将如下配置设置到 application.properties 里边,设置一下服务的端口号为 3333。

server.port=3333

management.endpoint.shutdown.enabled=true

management.endpoints.web.exposure.include=shutdown

接下来,咱们创建一个 Spring Boot 工程,然后设置一个 bean 对象,配置上 PreDestroy 方法。这样在停止的时候会打印语句。bean 的整个生命周期分为创建、初始化、销毁,当最后关闭的时候会执行销毁操作,在销毁的方法中执行一条输出日志。

package com.hqs.springboot.shutdowndemo.bean;

import javax.annotation.PreDestroy;

/**

* @author huangqingshi

* @Date 2019-08-17

*/

public class TerminateBean {

@PreDestroy

public void preDestroy() {

System.out.println("TerminalBean is destroyed");

}

}

做一个 configuration,然后提供一个获取 bean 的方法,这样该 bean 对象会被初始化。

package com.hqs.springboot.shutdowndemo.config;

import com.hqs.springboot.shutdowndemo.bean.TerminateBean;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

/**

* @author huangqingshi

* @Date 2019-08-17

*/

@Configuration

public class ShutDownConfig {

@Bean

public TerminateBean getTerminateBean() {

return new TerminateBean();

}

}

在启动类里边输出一个启动日志,当工程启动的时候,会看到启动的输出,接下来咱们执行停止命令。

curl -X POST http://localhost:3333/actuator/shutdown

以下日志可以输出启动时的日志打印和停止时的日志打印,同时程序已经停止,是不是比较神奇。

第二种方法也比较简单,获取程序启动时候的 context,然后关闭主程序启动时的 context。这样程序在关闭的时候也会调用 PreDestroy 注解,如下方法在程序启动十秒后进行关闭。

/* method 2: use ctx.close to shutdown all application context */

ConfigurableApplicationContext ctx = SpringApplication.run(ShutdowndemoApplication.class, args);

try {

TimeUnit.SECONDS.sleep(10);

} catch (InterruptedException e) {

e.printStackTrace();

}

ctx.close();

第三种方法,在 Spring Boot 启动的时候将进程号写入一个 app.pid 文件,生成的路径是可以指定的,可以通过命令 cat /Users/huangqingshi/app.id | xargs kill 命令直接停止服务,这个时候 bean 对象的 PreDestroy 方法也会调用的。这种方法大家使用的比较普遍。写一个 start.sh 用于启动 Spring Boot 程序,然后写一个停止程序将服务停止。

/* method 3 : generate a pid in a specified path, while use command to shutdown pid :

'cat /Users/huangqingshi/app.pid | xargs kill' */

SpringApplication application = new SpringApplication(ShutdowndemoApplication.class);

application.addListeners(new ApplicationPidFileWriter("/Users/huangqingshi/app.pid"));

application.run();

第四种方法,通过调用一个 SpringApplication.exit() 方法也可以退出程序,同时将生成一个退出码,这个退出码可以传递给所有的 context。

这个就是一个 JVM 的钩子,通过调用这个方法的话会把所有 PreDestroy 的方法执行并停止,并且传递给具体的退出码给所有 Context。通过调用 System.exit(exitCode) 可以将这个错误码也传给 JVM。程序执行完后最后会输出:Process finished with exit code 0,给 JVM 一个 SIGNAL。

/* method 4: exit this application using static method */

ConfigurableApplicationContext ctx = SpringApplication.run(ShutdowndemoApplication.class, args);

exitApplication(ctx);

public static void exitApplication(ConfigurableApplicationContext context) {

int exitCode = SpringApplication.exit(context, (ExitCodeGenerator) () -> 0);

System.exit(exitCode);

}

第五种方法,自己写一个 Controller,然后将自己写好的 Controller 获取到程序的 context,然后调用自己配置的 Controller 方法退出程序。

通过调用自己写的 /shutDownContext 方法关闭程序:curl -X POST http://localhost:3333/shutDownContext。

package com.hqs.springboot.shutdowndemo.controller;

import org.springframework.beans.BeansException;

import org.springframework.context.ApplicationContext;

import org.springframework.context.ApplicationContextAware;

import org.springframework.context.ConfigurableApplicationContext;

import org.springframework.web.bind.annotation.GetMapping;

import org.springframework.web.bind.annotation.PostMapping;

import org.springframework.web.bind.annotation.RestController;

/**

* @author huangqingshi

* @Date 2019-08-17

*/

@RestController

public class ShutDownController implements ApplicationContextAware {

private ApplicationContext context;

@PostMapping("/shutDownContext")

public String shutDownContext() {

ConfigurableApplicationContext ctx = (ConfigurableApplicationContext) context;

ctx.close();

return "context is shutdown";

}

@GetMapping("/")

public String getIndex() {

return "OK";

}

@Override

public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {

context = applicationContext;

}

}

好了,Spring Boot 的优雅关闭方法也都实现好了,也有同学问,如何暴力停止呢,简单,直接 kill -9 相应的 PID 即可。

总结

以上这几种方法实现的话比较简单,但是真实工作中还需要考虑的点还很多,比如需要保护暴露的点不被别人利用,一般要加一些防火墙,或者只在内网使用,保证程序安全。

在真实的工作中的时候第三种比较常用,程序中一般使用内存队列或线程池的时候最好要优雅的关机,将内存队列没有处理的保存起来或线程池中没处理完的程序处理完。但是因为停机的时候比较快,所以停服务的时候最好不要处理大量的数据操作,这样会影响程序停止。

所谓技多不压身,我们所读过的每一本书,所学过的每一门语言,在未来指不定都能给我们意想不到的回馈呢。其实做为一个开发者,有一个学习的氛围跟一个交流圈子特别重要这里我推荐一个Java学习交流群私信小编回复JAVA获得进群资料,不管你是小白还是大牛欢迎入驻,大家一起交流成长。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/434877.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Office - 安装程序找不到office.zh-cn\*.文件

Office - 安装程序找不到office.zh-cn\*.文件 在同时安装vs2008 和 office2007 有可能会遇到个问题&#xff08;如果现在安装office2007&#xff0c;在安装vs2008 不会出现问题&#xff0c; 反正会出现下面问题&#xff09;在安装office2007时总是提示“安装程序找不到 offi…

批量导出部分依赖图(PDP)

部分依赖图 (PDP) 和个体条件期望 (ICE) 图可用于可视化和分析目标响应1与一组感兴趣的输入特征之间的交互。 部分依赖图 (PDP) 显示了目标响应与一组感兴趣的输入特征之间的依赖关系&#xff0c;边缘化了所有其他输入特征&#xff08;“补充”特征&#xff09;的值。直观地说…

c#读蓝牙数据_CSharp--BlueTooth 实现蓝牙通讯的程序 C#开发 可以发送和接收数据 方便二次开发 - 下载 - 搜珍网...

蓝牙C#/BluetoothDemo/bin/Debug/BluetoothDemo.exe蓝牙C#/BluetoothDemo/bin/Debug/OpenNETCF.BluetoothEx.dll蓝牙C#/BluetoothDemo/BluetoothDemo.csproj蓝牙C#/BluetoothDemo/BluetoothDemo.csproj.user蓝牙C#/BluetoothDemo/frmMain.cs蓝牙C#/BluetoothDemo/frmMain.Desig…

基于SDP的提议/应答(offer/answer)模型简介

1、引入 在松耦合会议中&#xff0c;会话参数完全由会议创建者来确定&#xff0c;参与者能做的仅仅是根据这些会话参数来加入会议&#xff08;当然也可以选择不加入&#xff09;。这种情况下&#xff0c;主要要做的就是会话描述&#xff0c;在这里SDP本身就足够了。 但是在更为…

arcgis已知两点投影坐标求距离

问题&#xff1a; 已知中心点坐标&#xff0c;求个点与中心点坐标的距离 解决方法如下&#xff1a; 新建字段 在新建字段上右键字段计算器 利用字段计算器进行两点间距离计算 不懂问题请进群交流询问相关知识点

【原创】StreamInsight查询系列(十九)——查询模式之检测异常

上篇文章介绍了查询模式中如何发现趋势&#xff0c;这篇博文将介绍StreamInsight中如何检测异常。 测试数据准备 为了方便测试查询&#xff0c;我们首先准备一个静态的测试数据源&#xff1a;var now DateTime.Parse("09/12/2011 8:57:00 PM"); var input new[] {n…

tensorflow 旋转图片_使用TensorFlow对图像进行随机旋转的实现示例

https://www.jb51.net/article/178934.htm在使用深度学习对图像进行训练时&#xff0c;对图像进行随机旋转有助于提升模型泛化能力。然而之前在做旋转等预处理工作时&#xff0c;都是先对图像进行旋转后保存到本地&#xff0c;然后再输入模型进行训练&#xff0c;这样的过程会增…

SIP协议详解

SIP协议概念** 会话启动协议SIP&#xff08;Session Initiation Protocol&#xff09;是一个在IP网络上进行多媒体通信的应用层控制协议&#xff0c;它被用来创 建、修改、和终结一个或多个参加者参加的会话进程。 **SIP协议可用于发起会话&#xff0c;也可以用于邀请成员加入…

arcgis判断两个字段是否相等

def a(b,c):if(bc):return 1else:return 0 不懂问题请进群交流

深入浅出InfoPath——动态获取InfoPath中的命名空间

问题描述&#xff1a;我们在不同的开发Server和Product环境中部署InfoPath的时候&#xff0c;发现命名空间会随InfoPath的小版本变化而变化。 比如&#xff1a;http://schemas.microsoft.com/office/infopath/2003/myXSD/2011-03-14T09:12:19 处理办法&#xff1a; 使用Linq to…

一元三次方程重根判别式_许兴华——关于复数集中解一元二次方程的问题

在学习复数时&#xff0c;最近有个别比较好学的同学提出一个问题&#xff1a;“对于复数系数一元二次方程&#xff0c;是否可以用求根公式求解呢&#xff1f;”——回答是肯定的&#xff01;关于复数集中解一元二次方程的问题。其实&#xff0c;在复数集内解关于x的一元二次方程…

arcgis批量将栅格里的nodata转为0

新建模型 修改名称 在arcgis的工具箱中新建一个模型&#xff0c;具体模型如下 模型里的具体参数如下 1.栅格计算器 2.输出路径&#xff0c;%—%这样的的输出可以保留之前的文件的名称 不懂问题请进群交流

基于SIP协议的视频通讯

1.sip协议及其发展 sip&#xff08;session initiation protocal&#xff09;称为会话发起协议&#xff0c;是由ietf&#xff08;internet engineering task force&#xff09;组织于1999年提出的一个在基于ip网络中&#xff0c;特别是在internet这样一种结构的网络环境中&…

hive sql 怎么实现循环_Hive存储过程实现-hpsql

1. 什么是hpsql目前版本的hive中没有提供类似存储过程的功能&#xff0c;使用Hive做数据开发时候&#xff0c;一般是将一段一段的HQL语句封装在Shell或者其他脚本中&#xff0c;然后以命令行的方式调用&#xff0c;完成一个业务或者一张报表的统计分析。好消息是&#xff0c;现…

解决若干WTL与VS2010的兼容问题(如error MSB6006: “cmd.exe”)

解决[error MSB6006: “cmd.exe” 已退出&#xff0c;代码为 9009。]问题: The AppWizard for VS2010 above has two small glitches (however they might deter people from using WTL with VS2010). These are very easy to fix: 1) [Output Directory] and [Intermediate Di…

arcgis中制作复杂符号

简介 在arcgis制图中常会遇到复杂的制图符号,如下 通过平常的代码显示并不会显示原图这样的效果,接下来我们开始解决改问题 主要思想: 通过字体文件将其显示 所以的软件: arcgis和FontCreator FontCreator软件下载链接

vb 通过php连接mysql数据库连接_PHP连接MySQL数据库的几种方法

1.最简单的方式-mysql(面向过程)$con mysql_connect("localhost","root","password");$select_db mysql_select_db(test);if (!$select_db) {die("could not connect to the db:\n" . mysql_error());}//查询代码$sql "select…

处理硬件设备访问权限问题

在硬件抽象层模块中&#xff0c;我们是调用open函数来打开对应的设备文件的。例如&#xff0c;在2.3.2小节中开发的硬件抽象层模块freg中&#xff0c;函数freg_device_open调用open函数来打开设备文件/dev/freg。 60 if((dev->fd open(DEVICE_NAME, O_RDWR)) -1) { 61 …

根据rtk参数在arcgis中进行可视化

RTK原始文件 通过原始文件发现&#xff0c;arcgis中并没有中央经线是113的CGS2000投影坐标&#xff0c;所以此处需要进行自定义投影转换 不懂问题请进群交流

django图片上传到oss_django 配置阿里云OSS存储media文件的例子

1. 安装django-aliyun-oss2-storage包linux上用 pip install django-aliyun-oss2-storage 无报错&#xff0c;顺利安装windows上报错:(python3_sbs) F:\projects\virtualenv\python3_sbs\Scripts>pip install django-aliyun-oss2-storageCollecting django-aliyun-oss2-stor…