5 changed files with 109 additions and 1 deletions
@ -0,0 +1,24 @@ |
|||
package com.epmet.config; |
|||
|
|||
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; |
|||
import org.springframework.boot.web.embedded.tomcat.TomcatServletWebServerFactory; |
|||
import org.springframework.boot.web.servlet.server.ServletWebServerFactory; |
|||
import org.springframework.context.annotation.Bean; |
|||
import org.springframework.context.annotation.Configuration; |
|||
|
|||
/** |
|||
* 优雅停机配置 |
|||
* matchIfMissing:当缺少shutdown.graceful.enable配置的时候,是否加载该配置类。true:缺少也加载,false:默认的,缺少配置不加载,即不生效 |
|||
*/ |
|||
@Configuration |
|||
@ConditionalOnProperty(prefix = "shutdown.graceful", name = "enable", havingValue = "true", matchIfMissing = false) |
|||
public class GracefulShutdownConfig { |
|||
|
|||
@Bean |
|||
public ServletWebServerFactory servletContainer(GracefulShutdownTomcat gracefulShutdownTomcat) { |
|||
TomcatServletWebServerFactory tomcat = new TomcatServletWebServerFactory(); |
|||
tomcat.addConnectorCustomizers(gracefulShutdownTomcat); |
|||
return tomcat; |
|||
} |
|||
|
|||
} |
@ -0,0 +1,52 @@ |
|||
package com.epmet.config; |
|||
|
|||
import com.epmet.commons.tools.exception.RenException; |
|||
import net.bytebuddy.implementation.bytecode.Throw; |
|||
import org.apache.catalina.connector.Connector; |
|||
import org.slf4j.Logger; |
|||
import org.slf4j.LoggerFactory; |
|||
import org.springframework.beans.factory.annotation.Autowired; |
|||
import org.springframework.boot.context.properties.EnableConfigurationProperties; |
|||
import org.springframework.boot.web.embedded.tomcat.TomcatConnectorCustomizer; |
|||
import org.springframework.context.ApplicationListener; |
|||
import org.springframework.context.event.ContextClosedEvent; |
|||
import org.springframework.stereotype.Component; |
|||
|
|||
import java.util.concurrent.Executor; |
|||
import java.util.concurrent.ThreadPoolExecutor; |
|||
import java.util.concurrent.TimeUnit; |
|||
|
|||
@EnableConfigurationProperties(ShutdownProperties.class) |
|||
@Component |
|||
public class GracefulShutdownTomcat implements TomcatConnectorCustomizer, ApplicationListener<ContextClosedEvent> { |
|||
|
|||
private static final Logger logger = LoggerFactory.getLogger(GracefulShutdownTomcat.class); |
|||
|
|||
@Autowired |
|||
private ShutdownProperties shutdownProperties; |
|||
|
|||
private volatile Connector connector; |
|||
|
|||
@Override |
|||
public void customize(Connector connector) { |
|||
this.connector = connector; |
|||
} |
|||
@Override |
|||
public void onApplicationEvent(ContextClosedEvent contextClosedEvent) { |
|||
this.connector.pause(); |
|||
Executor executor = this.connector.getProtocolHandler().getExecutor(); |
|||
long waitTimeSecs = shutdownProperties.getGraceful().getWaitTimeSecs(); |
|||
if (executor instanceof ThreadPoolExecutor) { |
|||
try { |
|||
ThreadPoolExecutor threadPoolExecutor = (ThreadPoolExecutor) executor; |
|||
threadPoolExecutor.shutdown(); |
|||
if (!threadPoolExecutor.awaitTermination(waitTimeSecs, TimeUnit.SECONDS)) { |
|||
String msg = String.format("Tomcat在【%s】秒内优雅停机失败,请手动处理", waitTimeSecs); |
|||
logger.error(msg); |
|||
} |
|||
} catch (InterruptedException ex) { |
|||
Thread.currentThread().interrupt(); |
|||
} |
|||
} |
|||
} |
|||
} |
@ -0,0 +1,17 @@ |
|||
package com.epmet.config; |
|||
|
|||
import lombok.Data; |
|||
import org.springframework.boot.context.properties.ConfigurationProperties; |
|||
|
|||
@ConfigurationProperties(prefix = "shutdown") |
|||
@Data |
|||
public class ShutdownProperties { |
|||
|
|||
private GracefulShutdownProperties graceful; |
|||
|
|||
@Data |
|||
public static class GracefulShutdownProperties { |
|||
private long waitTimeSecs = 30; |
|||
} |
|||
|
|||
} |
Loading…
Reference in new issue