Springboot项目平滑关闭及自动化关闭脚本
Springboot项目平滑关闭及自动化关闭脚本,供大家参考,具体内容如下
核心代码
- GracefulShutdown.java
- Shutdown.java
- ApplicationStarterRunner.java
- CommonInfo.java
- HttpCommonUtil.java
- application.properties
操作步骤
核心代码
GracefulShutdown.java
packagecnkj.site.utils; importorg.apache.catalina.LifecycleException; importorg.apache.catalina.connector.Connector; importorg.apache.catalina.util.LifecycleBase; importorg.slf4j.Logger; importorg.slf4j.LoggerFactory; importorg.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer; importorg.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; importorg.springframework.boot.web.servlet.server.ConfigurableServletWebServerFactory; importorg.springframework.context.ApplicationListener; importorg.springframework.context.annotation.Bean; importorg.springframework.context.event.ContextClosedEvent; importjava.util.concurrent.Executor; importjava.util.concurrent.ThreadPoolExecutor; importjava.util.concurrent.TimeUnit; /* *@version1.0createdbyCarolon2019/4/2516:22 */ publicclassGracefulShutdownimplementsTomcatConnectorCustomizer,ApplicationListener{ privatestaticfinalLoggerLOGGER=LoggerFactory.getLogger(GracefulShutdown.class); privatevolatileConnectorconnector; @Override publicvoidcustomize(Connectorconnector){ this.connector=connector; } @Override publicvoidonApplicationEvent(ContextClosedEventevent){ try{ //指定执行的方法 shutdown(); //手动清理内存 System.gc(); LOGGER.warn("清理内存完毕,正在退出服务......"); if(this.connector==null){ return; } this.connector.pause(); LOGGER.warn("关闭全部连接......"); Executorexecutor=this.connector.getProtocolHandler().getExecutor(); if(executorinstanceofThreadPoolExecutor){ try{ ThreadPoolExecutorthreadPoolExecutor=(ThreadPoolExecutor)executor; threadPoolExecutor.shutdown(); LOGGER.warn("当前服务线程池被关闭"); if(!threadPoolExecutor.awaitTermination(30,TimeUnit.SECONDS)){ LOGGER.warn("Tomcatthreadpooldidnotshutdowngracefullywithin30seconds.Proceedingwithforcefulshutdown"); } }catch(InterruptedExceptionex){ Thread.currentThread().interrupt(); } } this.connector.stop(); }catch(LifecycleExceptione){ e.printStackTrace(); } } @Bean publicGracefulShutdowngracefulShutdown(){ returnnewGracefulShutdown(); } @Bean publicConfigurableServletWebServerFactorywebServerFactory(finalGracefulShutdowngracefulShutdown){ TomcatServletWebServerFactoryfactory=newTomcatServletWebServerFactory(); factory.addConnectorCustomizers(gracefulShutdown); returnfactory; } /** *执行服务关闭前的一些定制化操作 *通常需要确认以下步骤 *1.关闭kafka等数据连接 *2.flush内存中全部的未处理数据 *3.清理服务中全部待处理的数据 */ publicvoidshutdown(){} }
Shutdown.java
importcnkj.site.utils.GracefulShutdown; importorg.springframework.stereotype.Component; /* *@version1.0createdbyCarolon2019/4/2516:39 */ @Component publicclassShutdownextendsGracefulShutdown{ @Override publicvoidshutdown(){ //TODO定制化关闭操作流程 //关闭kafka消费 //flush全部读写流 //清空队列 //关闭全部文件流读写 } }
ApplicationStarterRunner.java
packagecn.migu.log.component; importcnkj.site.utils.HttpCommonUtil; importcnkj.site.CommonInfo; importorg.springframework.boot.CommandLineRunner; importorg.springframework.stereotype.Component; /* *@version1.0createdbyLXWon2019/3/1417:05 */ @Component publicclassApplicationStarterRunnerimplementsCommandLineRunner{ @Override publicvoidrun(String...args)throwsException{ //设置服务名 commonInfo.setSERVICE_NAME("Service-Name"); //自动设置服务启动后的进程号 commonInfo.setSERVICE_PID(HttpCommonUtil.getCurrentPid()); } }
CommonInfo.java
packagecnkj.site.utils; importlombok.Builder; importlombok.Data; importorg.springframework.boot.actuate.info.Info; importorg.springframework.boot.actuate.info.InfoContributor; importorg.springframework.stereotype.Component; importjava.util.HashMap; importjava.util.Map; @Data @Component publicclassCommonInfoimplementsInfoContributor{ //当前服务名 privateStringSERVICE_NAME="SERVICE_NAME"; //服务当前状态 privateintSERVICE_PID; @Override publicvoidcontribute(Info.Builderbuilder){ builder.withDetail("SERVICE_NAME",SERVICE_NAME); builder.withDetail("SERVICE_PID",SERVICE_PID); } publicvoidclearAll(){ this.SERVICE_NAME=""; this.SERVICE_PID=-1; } publicMapgetAll(){ Mapmap=newHashMap(); map.put("SERVICE_NAME",getSERVICE_NAME()); map.put("SERVICE_PID",getSERVICE_PID()); returnmap; } }
HttpCommonUtil.java
packagecnkj.site.utils; importjavax.servlet.http.HttpServletRequest; importjava.lang.management.ManagementFactory; importjava.net.InetAddress; importjava.net.UnknownHostException; /* *@version1.0createdbyCarolon2018/10/2510:04 */ publicclassHttpCommonUtil{ /** *获取当前服务的PID *@returnPID */ publicstaticIntegergetCurrentPid(){ Stringname=ManagementFactory.getRuntimeMXBean().getName(); Stringpid=name.split("@")[0]; returnInteger.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文件的最下面新增exportPATH=/data/shell/server_close:$PATH
6.保存并退出:wq
7.如果提示/bin/bash^M:badinterpreter:Nosuchfileordirectory,请vimserviceControll.sh,然后:setfileformat=unix,然后:wq保存并退出即可
8.cd/data/shell/server_close&./serviceControll.sh运行即可使用服务关闭脚本
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。