Commit cc27be8e authored by xiaoguang.xu's avatar xiaoguang.xu

feature: 1. 增加对容器判断的日志打印, 采用spring 源生的判断方法 2. 修正了MQ停止的部分情况下错误. 3. 调整了目录结构. starter形式

parent be6cfe74
...@@ -5,7 +5,7 @@ ...@@ -5,7 +5,7 @@
<parent> <parent>
<artifactId>commons-parent</artifactId> <artifactId>commons-parent</artifactId>
<groupId>cn.quantgroup</groupId> <groupId>cn.quantgroup</groupId>
<version>0.1.4</version> <version>0.1.5</version>
</parent> </parent>
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
...@@ -35,41 +35,9 @@ ...@@ -35,41 +35,9 @@
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId> <artifactId>spring-boot-starter-web</artifactId>
<scope>compile</scope> <scope>compile</scope>
<exclusions>
<exclusion>
<artifactId>spring-boot-starter-tomcat</artifactId>
<groupId>*</groupId>
</exclusion>
<exclusion>
<artifactId>jboss-servlet-api_3.1_spec</artifactId>
<groupId>org.jboss.spec.javax.servlet</groupId>
</exclusion>
<exclusion>
<artifactId>commons-logging</artifactId>
<groupId>commons-logging</groupId>
</exclusion>
<exclusion>
<artifactId>annotations</artifactId>
<groupId>com.google.code.findbugs</groupId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
<optional>true</optional>
</dependency> </dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-security</artifactId> <artifactId>spring-boot-starter-security</artifactId>
...@@ -122,11 +90,6 @@ ...@@ -122,11 +90,6 @@
<artifactId>lombok</artifactId> <artifactId>lombok</artifactId>
<version>1.16.16</version> <version>1.16.16</version>
</dependency> </dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
<optional>true</optional>
</dependency>
<dependency> <dependency>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
......
package cn.quantgroup.tech.autoconfigure; package cn.quantgroup.tech.autoconfigure;
import cn.quantgroup.tech.endpoint.HealthCheckMvcEndpoint; import cn.quantgroup.tech.endpoint.HealthCheckMvcEndpoint;
import cn.quantgroup.tech.shutdown.DefaultSignalHandler;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.endpoint.EndpointProperties; import org.springframework.boot.actuate.endpoint.EndpointProperties;
import org.springframework.boot.autoconfigure.AutoConfigureAfter; import org.springframework.boot.autoconfigure.AutoConfigureAfter;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration; import org.springframework.boot.autoconfigure.flyway.FlywayAutoConfiguration;
import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration; import org.springframework.boot.autoconfigure.liquibase.LiquibaseAutoConfiguration;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import sun.misc.Signal;
/** /**
* @author jinsong.zhu * @author jinsong.zhu
* @date 2017/12/18 * @date 2017/12/18
*/ */
@Slf4j
@Configuration @Configuration
@AutoConfigureAfter({FlywayAutoConfiguration.class, LiquibaseAutoConfiguration.class}) @AutoConfigureAfter({FlywayAutoConfiguration.class, LiquibaseAutoConfiguration.class})
@EnableConfigurationProperties(EndpointProperties.class) @EnableConfigurationProperties(EndpointProperties.class)
public class TechCommonAutoConfiguration { public class TechCommonAutoConfiguration {
ConfigurableApplicationContext applicationContext;
@Autowired
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = (ConfigurableApplicationContext) applicationContext;
initSignalHandler(this.applicationContext);
}
private void initSignalHandler(ConfigurableApplicationContext applicationContext) {
log.info("starting init graceful shutdown by listening on int signal .");
Signal.handle(new Signal("INT"), new DefaultSignalHandler(applicationContext));
}
@Bean @Bean
@ConditionalOnMissingBean @ConditionalOnMissingBean
public HealthCheckMvcEndpoint healthCheckMvcEndpoint() { public HealthCheckMvcEndpoint healthCheckMvcEndpoint() {
......
...@@ -21,6 +21,7 @@ public class HealthCheckMvcEndpoint implements MvcEndpoint { ...@@ -21,6 +21,7 @@ public class HealthCheckMvcEndpoint implements MvcEndpoint {
@RequestMapping(value = "check", method = {RequestMethod.GET, RequestMethod.POST}) @RequestMapping(value = "check", method = {RequestMethod.GET, RequestMethod.POST})
@ResponseBody @ResponseBody
public Result check() { public Result check() {
return Result.ok(); return Result.ok();
} }
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
<modelVersion>4.0.0</modelVersion> <modelVersion>4.0.0</modelVersion>
<groupId>cn.quantgroup</groupId> <groupId>cn.quantgroup</groupId>
<artifactId>commons-parent</artifactId> <artifactId>commons-parent</artifactId>
<version>0.1.4</version> <version>0.1.5</version>
<parent> <parent>
<groupId>org.springframework.boot</groupId> <groupId>org.springframework.boot</groupId>
...@@ -17,6 +17,7 @@ ...@@ -17,6 +17,7 @@
<modules> <modules>
<module>commons-core</module> <module>commons-core</module>
<module>commons-spring</module> <module>commons-spring</module>
<module>shutdown-spring-boot-starter</module>
</modules> </modules>
<packaging>pom</packaging> <packaging>pom</packaging>
...@@ -43,12 +44,17 @@ ...@@ -43,12 +44,17 @@
<dependency> <dependency>
<groupId>cn.quantgroup</groupId> <groupId>cn.quantgroup</groupId>
<artifactId>commons-spring</artifactId> <artifactId>commons-spring</artifactId>
<version>0.1.4</version> <version>0.1.5</version>
</dependency> </dependency>
<dependency> <dependency>
<groupId>cn.quantgroup</groupId> <groupId>cn.quantgroup</groupId>
<artifactId>commons-core</artifactId> <artifactId>commons-core</artifactId>
<version>0.1.4</version> <version>0.1.5</version>
</dependency>
<dependency>
<groupId>cn.quantgroup</groupId>
<artifactId>shutdown-spring-boot-starter</artifactId>
<version>0.1.5</version>
</dependency> </dependency>
</dependencies> </dependencies>
</dependencyManagement> </dependencyManagement>
......
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>commons-parent</artifactId>
<groupId>cn.quantgroup</groupId>
<version>0.1.5</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>shutdown-spring-boot-starter</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-autoconfigure</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jetty</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-amqp</artifactId>
<optional>true</optional>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
</project>
\ No newline at end of file
...@@ -8,6 +8,7 @@ import org.springframework.context.ApplicationContext; ...@@ -8,6 +8,7 @@ import org.springframework.context.ApplicationContext;
import org.springframework.context.Lifecycle; import org.springframework.context.Lifecycle;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy; import javax.annotation.PreDestroy;
/** /**
...@@ -22,6 +23,19 @@ public class BaseDestroyHandler { ...@@ -22,6 +23,19 @@ public class BaseDestroyHandler {
@Autowired @Autowired
private ApplicationContext applicationContext; private ApplicationContext applicationContext;
private RabbitListenerEndpointRegistry rabbitListenerEndpointRegistry;
@PostConstruct
public void initMQConf() {
try {
rabbitListenerEndpointRegistry = applicationContext.getBean(
RabbitListenerConfigUtils.RABBIT_LISTENER_ENDPOINT_REGISTRY_BEAN_NAME,
RabbitListenerEndpointRegistry.class);
} catch (Exception e) {
log.warn("注入MQ endpoint registry 失败, 如果你有MQ队列接收, 可能你要关注一下了");
}
}
@PreDestroy @PreDestroy
private void stopRedisSub() { private void stopRedisSub() {
log.info("我什么都没做, redis stopped"); log.info("我什么都没做, redis stopped");
...@@ -30,13 +44,14 @@ public class BaseDestroyHandler { ...@@ -30,13 +44,14 @@ public class BaseDestroyHandler {
@PreDestroy @PreDestroy
private void stopRabbitMQ() { private void stopRabbitMQ() {
try { try {
RabbitListenerEndpointRegistry rabbitListenerEndpointRegistry = applicationContext.getBean( if (rabbitListenerEndpointRegistry == null) {
RabbitListenerConfigUtils.RABBIT_LISTENER_ENDPOINT_REGISTRY_BEAN_NAME, log.warn("我什么都没做, MQ listener stopped");
RabbitListenerEndpointRegistry.class); return;
}
rabbitListenerEndpointRegistry.getListenerContainers().forEach(Lifecycle::stop); rabbitListenerEndpointRegistry.getListenerContainers().forEach(Lifecycle::stop);
} catch (Exception e) { } catch (Exception e) {
//貌似这段日志不会打印... //貌似这段日志不会打印...
log.error("貌似停止 MQ 遇到了问题... 你有MQ么? "); log.error("貌似停止 MQ 遇到了问题... 你有MQ么?", e);
} }
log.info("MQ listener stopped"); log.info("MQ listener stopped");
} }
......
...@@ -32,7 +32,9 @@ public class DefaultSignalHandler implements SignalHandler { ...@@ -32,7 +32,9 @@ public class DefaultSignalHandler implements SignalHandler {
log.info("servlet container 停止接收请求"); log.info("servlet container 停止接收请求");
} catch (InterruptedException e) { } catch (InterruptedException e) {
} }
log.info("{} 即将执行 @PreDestroy 方法", applicationName);
System.exit(0);
//处理无法exit(0)的动作
Thread.getAllStackTraces().forEach((thread, stackTraceElements) -> { Thread.getAllStackTraces().forEach((thread, stackTraceElements) -> {
if (!thread.isDaemon()) { if (!thread.isDaemon()) {
//如果中断 daemon 线程, 会导致 PreDestroy 方法不执行, //如果中断 daemon 线程, 会导致 PreDestroy 方法不执行,
...@@ -41,7 +43,6 @@ public class DefaultSignalHandler implements SignalHandler { ...@@ -41,7 +43,6 @@ public class DefaultSignalHandler implements SignalHandler {
thread.interrupt(); thread.interrupt();
} }
}); });
log.info("{} 即将执行 @PreDestroy 方法", applicationName);
System.exit(0); System.exit(0);
} catch (Exception e) { } catch (Exception e) {
// 此处可能导致异常的里面包含了logback中类未能找到, 所以增加输出到控制台. // 此处可能导致异常的里面包含了logback中类未能找到, 所以增加输出到控制台.
......
package cn.quantgroup.tech.shutdown.configuration; package cn.quantgroup.tech.shutdown.configuration;
import cn.quantgroup.tech.shutdown.DefaultSignalHandler;
import cn.quantgroup.tech.shutdown.properties.GracefulShutdownProperties; import cn.quantgroup.tech.shutdown.properties.GracefulShutdownProperties;
import cn.quantgroup.tech.shutdown.service.JettyShutdown; import cn.quantgroup.tech.shutdown.service.JettyShutdown;
import cn.quantgroup.tech.shutdown.service.TomcatShutdown; import cn.quantgroup.tech.shutdown.service.TomcatShutdown;
import cn.quantgroup.tech.shutdown.service.UndertowShutdown; import cn.quantgroup.tech.shutdown.service.UndertowShutdown;
import cn.quantgroup.tech.shutdown.wrapper.UndertowShutdownHandlerWrapper; import cn.quantgroup.tech.shutdown.wrapper.UndertowShutdownHandlerWrapper;
import io.undertow.Undertow; import io.undertow.Undertow;
import lombok.extern.slf4j.Slf4j;
import org.apache.catalina.startup.Tomcat; import org.apache.catalina.startup.Tomcat;
import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.util.Loader; import org.eclipse.jetty.util.Loader;
import org.eclipse.jetty.webapp.WebAppContext; import org.eclipse.jetty.webapp.WebAppContext;
import org.springframework.boot.autoconfigure.condition.ConditionalOnClass; import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; import org.springframework.boot.autoconfigure.AutoConfigureOrder;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; import org.springframework.boot.autoconfigure.condition.*;
import org.springframework.boot.autoconfigure.condition.SearchStrategy;
import org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration; import org.springframework.boot.autoconfigure.web.EmbeddedServletContainerAutoConfiguration;
import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer; import org.springframework.boot.context.embedded.EmbeddedServletContainerCustomizer;
import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory; import org.springframework.boot.context.embedded.EmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory; import org.springframework.boot.context.embedded.jetty.JettyEmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory; import org.springframework.boot.context.embedded.tomcat.TomcatEmbeddedServletContainerFactory;
import org.springframework.boot.context.embedded.undertow.UndertowDeploymentInfoCustomizer; import org.springframework.boot.context.embedded.undertow.UndertowDeploymentInfoCustomizer;
import org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainer;
import org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory; import org.springframework.boot.context.embedded.undertow.UndertowEmbeddedServletContainerFactory;
import org.springframework.boot.context.properties.EnableConfigurationProperties; import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ConfigurableApplicationContext;
import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Import; import org.springframework.context.annotation.Import;
import org.springframework.core.Ordered;
import org.xnio.SslClientAuthMode;
import sun.misc.Signal;
import javax.servlet.Servlet; import javax.servlet.Servlet;
...@@ -33,12 +40,26 @@ import javax.servlet.Servlet; ...@@ -33,12 +40,26 @@ import javax.servlet.Servlet;
* This configuration class will be picked up by Spring Boot's auto configuration capabilities as soon as it's * This configuration class will be picked up by Spring Boot's auto configuration capabilities as soon as it's
* on the classpath. * on the classpath.
*/ */
@Slf4j
@Configuration @Configuration
@ConditionalOnWebApplication
@ConditionalOnProperty(prefix = "shutdown.graceful", name = "enabled", havingValue = "true", matchIfMissing = true) @ConditionalOnProperty(prefix = "shutdown.graceful", name = "enabled", havingValue = "true", matchIfMissing = true)
@AutoConfigureOrder(Ordered.HIGHEST_PRECEDENCE)
@EnableConfigurationProperties(GracefulShutdownProperties.class) @EnableConfigurationProperties(GracefulShutdownProperties.class)
@Import(EmbeddedServletContainerAutoConfiguration.BeanPostProcessorsRegistrar.class) @Import(EmbeddedServletContainerAutoConfiguration.BeanPostProcessorsRegistrar.class)
public class GracefulShutdownAutoConfiguration { public class GracefulShutdownAutoConfiguration {
ConfigurableApplicationContext applicationContext;
@Autowired
public void setApplicationContext(ApplicationContext applicationContext) {
this.applicationContext = (ConfigurableApplicationContext) applicationContext;
log.info("注册对 Signal INT 信号的接收.");
Signal.handle(new Signal("INT"), new DefaultSignalHandler(this.applicationContext));
}
/** /**
* Configuration for Tomcat. * Configuration for Tomcat.
*/ */
...@@ -49,6 +70,7 @@ public class GracefulShutdownAutoConfiguration { ...@@ -49,6 +70,7 @@ public class GracefulShutdownAutoConfiguration {
@Bean @Bean
public TomcatShutdown tomcatShutdown() { public TomcatShutdown tomcatShutdown() {
log.info("容器是 tomcat,成功构造 shutdown hook.");
return new TomcatShutdown(); return new TomcatShutdown();
} }
...@@ -76,6 +98,7 @@ public class GracefulShutdownAutoConfiguration { ...@@ -76,6 +98,7 @@ public class GracefulShutdownAutoConfiguration {
@Bean @Bean
public JettyShutdown jettyShutdown() { public JettyShutdown jettyShutdown() {
log.info("容器是 jetty,成功构造 shutdown hook.");
return new JettyShutdown(); return new JettyShutdown();
} }
...@@ -100,12 +123,13 @@ public class GracefulShutdownAutoConfiguration { ...@@ -100,12 +123,13 @@ public class GracefulShutdownAutoConfiguration {
* Configuration for Undertow. * Configuration for Undertow.
*/ */
@Configuration @Configuration
@ConditionalOnClass({Servlet.class, Undertow.class}) @ConditionalOnClass({ Servlet.class, Undertow.class, SslClientAuthMode.class })
@ConditionalOnMissingBean(value = EmbeddedServletContainerFactory.class, search = SearchStrategy.CURRENT) @ConditionalOnMissingBean(value = EmbeddedServletContainerFactory.class, search = SearchStrategy.CURRENT)
public static class EmbeddedUndertow { public static class EmbeddedUndertow {
@Bean @Bean
public UndertowShutdown undertowShutdown() { public UndertowShutdown undertowShutdown() {
log.info("容器是 undertow,成功构造 shutdown hook.");
return new UndertowShutdown(); return new UndertowShutdown();
} }
......
org.springframework.boot.autoconfigure.EnableAutoConfiguration=\
cn.quantgroup.tech.shutdown.configuration.GracefulShutdownAutoConfiguration
\ No newline at end of file
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment