Springboot项目平滑关闭及自动化关闭脚本
程序员文章站
2024-02-22 10:56:10
springboot项目平滑关闭及自动化关闭脚本,供大家参考,具体内容如下
核心代码
gracefulshutdown.java
shutdown.jav...
springboot项目平滑关闭及自动化关闭脚本,供大家参考,具体内容如下
核心代码
- gracefulshutdown.java
- shutdown.java
- applicationstarterrunner.java
- commoninfo.java
- httpcommonutil.java
- application.properties
操作步骤
核心代码
gracefulshutdown.java
package cnkj.site.utils; import org.apache.catalina.lifecycleexception; import org.apache.catalina.connector.connector; import org.apache.catalina.util.lifecyclebase; import org.slf4j.logger; import org.slf4j.loggerfactory; import org.springframework.boot.web.embedded.tomcat.tomcatconnectorcustomizer; import org.springframework.boot.web.embedded.tomcat.tomcatservletwebserverfactory; import org.springframework.boot.web.servlet.server.configurableservletwebserverfactory; import org.springframework.context.applicationlistener; import org.springframework.context.annotation.bean; import org.springframework.context.event.contextclosedevent; import java.util.concurrent.executor; import java.util.concurrent.threadpoolexecutor; import java.util.concurrent.timeunit; /* * @version 1.0 created by carol on 2019/4/25 16:22 */ public class gracefulshutdown implements tomcatconnectorcustomizer, applicationlistener<contextclosedevent> { private static final logger logger = loggerfactory.getlogger(gracefulshutdown.class); private volatile connector connector; @override public void customize(connector connector) { this.connector = connector; } @override public void onapplicationevent(contextclosedevent event) { try { // 指定执行的方法 shutdown(); //手动清理内存 system.gc(); logger.warn("清理内存完毕,正在退出服务......"); if (this.connector == null){ return; } this.connector.pause(); logger.warn("关闭全部连接......"); executor executor = this.connector.getprotocolhandler().getexecutor(); if (executor instanceof threadpoolexecutor) { try { threadpoolexecutor threadpoolexecutor = (threadpoolexecutor) executor; threadpoolexecutor.shutdown(); logger.warn("当前服务线程池被关闭"); if (!threadpoolexecutor.awaittermination(30, timeunit.seconds)) { logger.warn("tomcat thread pool did not shut down gracefully within 30 seconds. proceeding with forceful shutdown"); } } catch (interruptedexception ex) { thread.currentthread().interrupt(); } } this.connector.stop(); } catch (lifecycleexception e) { e.printstacktrace(); } } @bean public gracefulshutdown gracefulshutdown() { return new gracefulshutdown(); } @bean public configurableservletwebserverfactory webserverfactory(final gracefulshutdown gracefulshutdown) { tomcatservletwebserverfactory factory = new tomcatservletwebserverfactory(); factory.addconnectorcustomizers(gracefulshutdown); return factory; } /** * 执行服务关闭前的一些定制化操作 * 通常需要确认以下步骤 * 1.关闭kafka等数据连接 * 2.flush内存中全部的未处理数据 * 3.清理服务中全部待处理的数据 */ public void shutdown(){} }
shutdown.java
import cnkj.site.utils.gracefulshutdown; import org.springframework.stereotype.component; /* * @version 1.0 created by carol on 2019/4/25 16:39 */ @component public class shutdown extends gracefulshutdown { @override public void shutdown() { // todo 定制化关闭操作流程 // 关闭 kafka 消费 // flush全部读写流 // 清空队列 // 关闭全部文件流读写 } }
applicationstarterrunner.java
package cn.migu.log.component; import cnkj.site.utils.httpcommonutil; import cnkj.site.commoninfo; import org.springframework.boot.commandlinerunner; import org.springframework.stereotype.component; /* * @version 1.0 created by lxw on 2019/3/14 17:05 */ @component public class applicationstarterrunner implements commandlinerunner { @override public void run(string... args) throws exception { // 设置服务名 commoninfo.setservice_name("service-name"); // 自动设置服务启动后的进程号 commoninfo.setservice_pid(httpcommonutil.getcurrentpid()); } }
commoninfo.java
package cnkj.site.utils; import lombok.builder; import lombok.data; import org.springframework.boot.actuate.info.info; import org.springframework.boot.actuate.info.infocontributor; import org.springframework.stereotype.component; import java.util.hashmap; import java.util.map; @data @component public class commoninfo implements infocontributor { //当前服务名 private string service_name="service_name"; //服务当前状态 private int service_pid; @override public void contribute(info.builder builder) { builder.withdetail("service_name",service_name); builder.withdetail("service_pid", service_pid); } public void clearall(){ this.service_name=""; this.service_pid=-1; } public map getall(){ map map = new hashmap(); map.put("service_name", getservice_name()); map.put("service_pid", getservice_pid()); return map; } }
httpcommonutil.java
package cnkj.site.utils; import javax.servlet.http.httpservletrequest; import java.lang.management.managementfactory; import java.net.inetaddress; import java.net.unknownhostexception; /* * @version 1.0 created by carol on 2018/10/25 10:04 */ public class httpcommonutil { /** * 获取当前服务的pid * @return pid */ public static integer getcurrentpid(){ string name = managementfactory.getruntimemxbean().getname(); string pid = name.split("@")[0]; return integer.valueof(pid); } }
application.properties
#服务关闭 management.endpoint.shutdown.enabled=true #监控相关 management.endpoint.prometheus.enabled=true management.endpoints.web.exposure.include=info
操作步骤
项目使用步骤:
1.拷贝上面的 shutdown.java 代码到自己的项目中
2.在 shutdown.java 文件中的shutdown 方法中写定制化的关闭操作流程
脚本使用步骤:
1.从git获取最新的项目关闭脚本 地址
2.压缩server_close 为server_close.zip
3.上传 server_close.zip 到你服务所在服务器上的 /data/shell 路径下
4.配置环境变量 vim /etc/profile
5.在profile文件的最下面新增 export path=/data/shell/server_close:$path
6.保存并退出 :wq
7.如果提示 /bin/bash^m: bad interpreter: no such file or directory,请vim servicecontroll.sh,然后 :set fileformat=unix ,然后 :wq 保存并退出即可
8.cd /data/shell/server_close & ./servicecontroll.sh 运行即可使用服务关闭脚本
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。