我正在尝试为我的spring启动应用程序添加SIGTERM支持。 为了测试它,我添加了一个应该模拟长请求的控制器映射:
@RequestMapping(value = "/sleep/{time}", method = RequestMethod.POST)
public void sleep(@PathVariable("time") int time) throws InterruptedException {
int sleepLimit = 30000;
if (time >= sleepLimit)
throw new IllegalArgumentException("Sleep time cannot be more than " + sleepLimit + " ms.");
Thread.sleep(time);
}
我使用嵌入式tomcat。 问题是在请求处于活动状态时向进程发送kill SIGTERM(使用CTRL + C,/ shutdown端点或docker中的shell脚本中的陷阱),应用程序“关闭”测试请求并且不等待调用完。 这是调用SIGTERM时的日志:
2015-12-26 20:22:43.812 INFO 11608 --- [ Thread-8] ationConfigEmbeddedWebApplicationContext : Closing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@548753b8: startup date [Sat Dec 26 20:22:13
IST 2015]; root of context hierarchy
2015-12-26 20:22:43.815 INFO 11608 --- [ Thread-8] o.s.c.support.DefaultLifecycleProcessor : Stopping beans in phase 0
2015-12-26 20:22:43.854 INFO 11608 --- [ Thread-8] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown
2015-12-26 20:22:43.856 INFO 11608 --- [ Thread-8] o.s.j.d.e.EmbeddedDatabaseFactory : Shutting down embedded database: url='jdbc:hsqldb:mem:testdb'
2015-12-26 20:22:43.880 INFO 11608 --- [ Thread-8] org.mongodb.driver.connection : Closed connection [connectionId{localValue:2, serverValue:2}] to 127.0.0.1:26140 because the pool has been closed.
2015-12-26 20:22:45.093 WARN 11608 --- [ Thread-3] d.f.e.p.store.CachingArtifactStore : Already removed de.flapdoodle.embed.process.extract.ImmutableExtractedFileSet@45524cfd for Version{3.0.2}:Windows:B64, emergency shutdown?
如何让我的应用程序等待此请求结束? 谢谢!
答案 0 :(得分:-1)
以下是我的解决方案:
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.actuate.metrics.CounterService;
import org.springframework.boot.actuate.metrics.buffer.BufferMetricReader;
import org.springframework.boot.context.embedded.FilterRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Service;
import javax.annotation.PreDestroy;
import javax.servlet.*;
import java.io.IOException;
@Service
@Scope("singleton")
public class ActiveSessionsService {
private static final org.slf4j.Logger logger = LoggerFactory.getLogger(ActiveSessionsService.class);
@Autowired
CounterService counterService;
@Autowired
BufferMetricReader metrics;
@Bean
public FilterRegistrationBean filterRegistrationBean() {
Filter filter = new Filter() {
@Override
public void init(FilterConfig filterConfig) throws ServletException {
}
@Override
public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
try {
counterService.increment("active-http-sessions");
filterChain.doFilter(servletRequest, servletResponse);
} finally {
counterService.decrement("active-http-sessions");
}
}
@Override
public void destroy() {
}
};
FilterRegistrationBean registrationBean = new FilterRegistrationBean();
registrationBean.setFilter(filter);
registrationBean.addUrlPatterns("/base/*");
return registrationBean;
}
@PreDestroy
public void cleanUp() throws Exception {
int waitTime=0;
while (waitTime < 10) {
if(!isThereActiveRequests())
break;
Thread.sleep(1000);
}
}
private boolean isThereActiveRequests() {
int activeCalls =metrics.findOne("counter.active-http-sessions").getValue().intValue();
logger.info(activeCalls +" Active sessions");
return activeCalls>0;
}
}