当前位置: 首页 > 知识库问答 >
问题:

Spring boot应用程序不等待SIGTERM

暴德运
2023-03-14

我正在尝试向我的spring boot应用程序添加一个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。问题在于,当请求处于活动状态时(在docker内部的shell脚本中使用CTRL C、/shutdown endpoint或trap),向进程发送kill SIGTERM时,应用程序会“关闭”测试请求,而不会等待调用完成。以下是调用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?

我如何让我的申请等待此请求结束?谢谢

共有1个答案

徐洛华
2023-03-14

以下是我的解决方案

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;
    }
}
 类似资料:
  • 我想暂停在JavaFX应用程序线程上执行方法并等待用户与UI交互。不要冻结UI很重要。 例子: 我应该如何实现< code>pause()和< code>resume()方法?< br >事件处理程序的执行应在< code>pause()处等待;调用,直到用户按下< code>resume按钮并且调用< code>resume方法。

  • 已经为此纠结了一天,来来回回看论坛,没有结果。任何人都可以告诉我为什么函数aMenu()的第二次调用返回一个零,而不等待新的用户输入?我尝试了各种方法,如hasNextInt()、nextLine(),但都不起作用。hasNextInt()不应该在用户写东西之前阻止吗?我该怎么解决这个?多谢了。

  • 到目前为止,我认为我已经掌握了async await如何使应用程序更具响应性的概念,但我有两点悬而未决: 层注意事项异步等待是否必须从存储库层一直到MVC或WCF层才能获得性能优势,或者我可以只对需要很长时间的存储库方法进行异步操作吗? “等待”用法如果我只能在存储库级别工作,有一部分我不明白。使用这种(低层)方法,线程能够在等待io绑定代码完成的同时为传入的客户端请求提供服务吗? 在我看来,当长

  • 我正在尝试将数据库调用移出控制器,以清理并使其可测试。当它们在控制器中时,一切都会顺利进行。我将它们移出控制器,并添加了一个异步,以确保我们等待。否则,我将调用的中的函数。现在,一旦我使用async/await,控制器中的函数就会认为没有用户,因为它没有等待。 有几个关于异步等待的SO问题,但我没有找到一个解决我的问题。我确实验证了返回了我的用户,并添加了控制台日志来显示路径。 节点猫鼬异步等待似

  • 我正在我的UI线程中调用一个方法。在这个方法中创建了一个新线程。我需要UI线程等待这个新线程完成,因为我需要这个线程的结果来继续UI线程中的方法。但我不想让UI在等待时冻结。有没有办法让UI线程在不忙的情况下等待?。

  • 我正试图将运行在tomcat上的现有应用程序更改为SpringBoot。它一直运行到真正的SpringBoot启动。我有一个类似的应用程序运行在SpringBoot上。这就是我知道它一直运行到Springboot的原因。 我的主要方法: 我尝试使用@componentscan运行main方法,该方法具有如下所示的basePackages: 这无济于事。我尝试在main类的顶部添加@SpringBo