2017-05-16 87 views
1

目標:使用嵌入式Jetty的Spring Web應用程序,我想關閉/重新啓動應用程序。
這裏的EmbeddedServletContainerFactory豆(如果需要的話,我會添加省略代碼):Spring + Jetty:優雅的關機

@Bean 
public EmbeddedServletContainerFactory jettyEmbeddedServletContainerFactory() { 
    JettyEmbeddedServletContainerFactory factory = new JettyEmbeddedServletContainerFactory(); 
    factory.addServerCustomizers(server -> { 

     server.setStopAtShutdown(false); 

     /* 
     * StatisticsHandler has to be added for graceful shutdown to work (see 
     * https://github.com/eclipse/jetty.project/issues/1549#issuecomment-301102535) 
     */ 
     StatisticsHandler statisticsHandler = new StatisticsHandler(); 
     statisticsHandler.setHandler(server.getHandler()); 
     server.setHandler(statisticsHandler); 
    }); 
    return factory; 
} 

,這裏是我們的關機信號處理程序:

@Component 
public class ShutdownSignalHandler { 

    @Value("${shutdown.signalType:TERM}") 
    private String signal; 

    @Autowired 
    private ConfigurableApplicationContext context; 

    @Autowired 
    private Server jetty; 

    @PostConstruct 
    public void init() { 
     Signal.handle(new Signal(signal), this::signalHandler); 
    } 

    private void signalHandler(Signal signal) { 
     jetty.stop(); 
     context.close(); 
    } 
} 

問題:具有上述配置,我每次重新啓動時間應用程序通過TERM信號,我在apache_access日誌中看到很多503條目(幾乎所有的都發生了,而jetty.stop正在執行)。
任何想法如何/爲什麼會發生和決議是什麼?

回答

1

爲什麼/它是如何發生的?那麼這是Jetty的默認行爲:首先,Jetty關閉網絡連接器以停止接受新連接,然後等待處理活動請求。但是,新的請求可能會通過已建立的連接(在關閉過程開始之前連接的連接)發送到Jetty。
解決方案:發送通過打開的連接發送的新請求的重試響應。我們定製了StatisticsHandler,以便在停止過程中不用503處理請求,而是使用307 Connection: close, Location: <original-url>來處理它們。

UPDATE:我們所做的是改變StatisticsHandler類的handle方法的實現(查找Change this line!評論):

@Override 
public void handle(String path, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException 
{ 
    ... 
    try 
    { 
     Handler handler = getHandler(); 
     if (handler!=null && _shutdown.get()==null && isStarted()) 
      handler.handle(path, baseRequest, request, response); 
     else if (baseRequest.isHandled()) 
     { 
      if (_wrapWarning.compareAndSet(false,true)) 
       LOG.warn("Bad statistics configuration. Latencies will be incorrect in {}",this); 
     } 
     else 
     { 
      baseRequest.setHandled(true); 
      response.sendError(HttpStatus.SERVICE_UNAVAILABLE_503); // Change this line! 
     } 
    } 
    finally 
    { 
     ... 
    } 
} 
+0

也許你可以在這裏發佈你的StatisticsHandler-customization? –

+1

@MarkusSchulte我添加了需要修改的部分。這不是特別的。我只是改變了我們想要的東西。只是一個快速的評論:由於處理流程複雜,我沒有試圖擴展它。我複製了整個代碼並更改了實現。 – Rad

-1

503 - 服務不可用

Apache可以不進行代理請求到servlet容器的時候,因爲沒有servlet容器監聽的主機上得到響應:端口代理配置中指定。

+1

我們沒有任何Apache。謝謝。 – Rad

+0

我雖然自從你提到「很多在apache_access日誌中的503個條目」 – ootero

+0

那麼這是Jetty日誌處理程序使用的名稱。 – Rad