java 如何优雅地关闭嵌入式码头

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/30347144/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-11-02 16:58:36  来源:igfitidea点击:

How to gracefully shutdown embeded jetty

javajettyembedded-jetty

提问by jos

I have an application runs on an embedded jetty server. Now i want to start/stop the server as a service. I use a script to start the server.

我有一个应用程序在嵌入式码头服务器上运行。现在我想启动/停止服务器作为服务。我使用脚本来启动服务器。

java $JAVA_OPTS -DREQ_JAVA_VERSION=$JAVA_VERSION -jar myjetty.jar

Main Class

主班

Server server = new Server();
SelectChannelConnector connector = new SelectChannelConnector();
connector.setPort(PORT);
server.addConnector(connector);
HandlerCollection handlers = new HandlerCollection();
NCSARequestLog requestLog = new NCSARequestLog();
requestLog.setFilename(home + "/logs/access_" + logFileDateFormat
            + ".log");
requestLog.setFilenameDateFormat(logFileDateFormat);
requestLog.setRetainDays(10);
requestLog.setAppend(true);
requestLog.setExtended(false);
requestLog.setLogCookies(false);
requestLog.setLogTimeZone(TimeZone.getDefault().getID());
RequestLogHandler requestLogHandler = new RequestLogHandler();
requestLogHandler.setRequestLog(requestLog);
handlers.addHandler(requestLogHandler);
server.setHandler(handlers);
server.start();
server.join();

This starts the server.Stopping and/or Restarting an embedded Jetty instance via web call can be used to stop server but, How to stop the server from the script? and what changes should i make to shout down server in the main class.

这将启动服务器。通过网络调用停止和/或重新启动嵌入式 Jetty 实例可用于停止服务器,但是,如何从脚本停止服务器?以及我应该做哪些更改以在主类中关闭服务器。

采纳答案by SubOptimal

There is no predefined solution to shut-down the Jetty server. The only ordered way to shut-down the Jetty server is to call the method stop()on the running server instance. You must implement the way how this method is called yourself.

没有预定义的解决方案来关闭 Jetty 服务器。关闭 Jetty 服务器的唯一有序方法是调用stop()正在运行的服务器实例上的方法。您必须自己实现调用此方法的方式。

You could achieve this (for example) by...

您可以通过以下方式实现(例如)...

  • implementing an RMI server thread and invoke the method from a RMI client
  • implementing a JMX MBean and from a client call a method on that MBean
  • implementing a custom handler like described in the link you have posted
  • 实现 RMI 服务器线程并从 RMI 客户端调用该方法
  • 实现 JMX MBean 并从客户端调用该 MBean 上的方法
  • 实现自定义处理程序,如您发布的链接中所述

If you only want to find a way which does not depend on additional tools like curl, than you could solve it for example like below (it's your own code with small modifications)

如果您只想找到一种不依赖于其他工具的方法,例如curl,那么您可以解决它,例如如下所示(这是您自己的代码,稍作修改)

public class MyJetty {

    public static void main(String[] args) throws Exception {
        int PORT = 9103;
        String home = System.getProperty("user.home");
        String logFileDateFormat = "yyyy_MM_dd";

        // execute a request to http://localhost:9103/stop
        // instead of `curl -v http://localhost:9103/stop`
        if (args.length == 1 && "stop".equalsIgnoreCase(args[0])) {
            URL url = new URL("http", "localhost", PORT, "/stop");
            try (InputStream in = url.openStream()) {
                int r;
                while ((r = in.read()) != -1) {
                    System.out.write(r);
                }
                return;
            } catch (IOException ex) {
                System.err.println("stop Jetty failed: " + ex.getMessage());
            }
        }

        Server server = new Server();
        SelectChannelConnector connector = new SelectChannelConnector();
        connector.setPort(PORT);
        server.addConnector(connector);
        HandlerCollection handlers = new HandlerCollection();
        NCSARequestLog requestLog = new NCSARequestLog();
        requestLog.setFilename(home + "/logs/access_" + logFileDateFormat + ".log");
        requestLog.setFilenameDateFormat(logFileDateFormat);
        requestLog.setRetainDays(10);
        requestLog.setAppend(true);
        requestLog.setExtended(false);
        requestLog.setLogCookies(false);
        requestLog.setLogTimeZone(TimeZone.getDefault().getID());
        RequestLogHandler requestLogHandler = new RequestLogHandler();
        requestLogHandler.setRequestLog(requestLog);
        handlers.addHandler(requestLogHandler);

        // the class YourHandler is the one from your link
        handlers.addHandler(new YourHandler(server));

        server.setHandler(handlers);
        server.start();
        server.join();
    }
}
  • start the server with java MyJetty
  • stop the server with java MyJetty stop
  • 启动服务器 java MyJetty
  • 停止服务器 java MyJetty stop

回答by diginoise

Since Jetty 7.5.xyou can use org.eclipse.jetty.server.handler.ShutdownHandlerin your code:

Jetty 7.5.x 开始,您可以org.eclipse.jetty.server.handler.ShutdownHandler在代码中使用:

Server server = new Server(8080);
HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[]
{ someOtherHandler, new ShutdownHandler("secret_password", false, true) });
server.setHandler(handlers);
server.start();

... which will allow you to shut down your jetty by issuing the following http POST request:

...这将允许您通过发出以下 http POST 请求来关闭您的码头:

curl -X POST http://localhost:8080/shutdown?token=secret_password

回答by bjrara

You can call setStopTimeout(long timeout) to shutdown Jetty in a relatively graceful way. A statisticsHandler must be configured when calling this method.

您可以调用 setStopTimeout(long timeout) 以相对优雅的方式关闭 Jetty。调用此方法时必须配置一个 statisticsHandler。

Referencing: Jetty Server.class setStopTimeout(long)

参考:Jetty Server.class setStopTimeout(long)

e.g.

例如

YourServletHandler servletHandler = new YourServletHandler();
StatisticsHandler statsHandler = new StatisticsHandler();
statsHandler.setHandler(servletHandler);

Server server = new Server(80);
server.setHandler(statsHandler);
server.setStopTimeout(3000L);

//...
server.start();

//...
server.stop();