2015-12-26 4 views
0

Я пытаюсь добавить поддержку SIGTERM в мое приложение загрузки весны. Для того чтобы проверить это я добавил отображение контроллера который должен имитировать длинный запрос:Приложение 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); 
} 

Я с помощью встроенного кота. Проблема заключается в отправке объекта SIGTERM в процесс, пока запрос активен (с использованием CTRL + C, конечной точки завершения или ловушки в сценарии оболочки внутри докера), приложение «закрывает» тестовый запрос и не дожидается вызова заканчивать. Вот лог при вызове SIGTERM:

2015-12-26 20:22:43.812 INFO 11608 --- [  Thread-8] ationConfigEmbeddedWebApplicationContext : Closing org.springframework.boot[email protected]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 [email protected]524cfd for Version{3.0.2}:Windows:B64, emergency shutdown? 

Как я могу сделать мое приложение, чтобы ждать этого запроса до конца? Спасибо!

+0

SIGTERM использует прерывания для обработки этого сигнала, как только вы можете написать собственный обработчик вы можете подключить этот процесс. –

+1

Я этого не знаю. Мне любопытно, что произойдет, если вы напишете метод destroy и аннотируете как предопределяете на своем сервисе. Ожидает ли весна, чтобы это закончилось? потому что может быть способ запросить любые запрошенные в настоящее время запросы и, возможно, дождаться, когда те прекратят или просто убьют их после определенного таймаута. Расскажите нам, как это происходит, если вы попробуете это. – MahdeTo

ответ

-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; 
    } 
} 
+0

При опускании, пожалуйста, оставьте комментарий ... –

Смежные вопросы