1

我已经编写了一个zuul 应用程序,并将默认的tomcat 替换为jetty。我为码头的高级配置(如线程池)实现了自己的 CustomJettyEmbeddedServletContainerFactory。

public class CustomJettyEmbeddedServletContainerFactory extends JettyEmbeddedServletContainerFactory {

private static final String SERVER_CONFIG = "/configuration/server/jetty/";
private static final String DISPLAY_NAME = "proxy-server";
private static final int HTTPS_PORT = 8443;

private static final int MIN_THREADS = 30;
private static final int MAX_THREADS = 2000;
private static final int QUEUE_SIZE = 60000;
private static final int TIME_OUT = 300000;
private static final int REQUEST_HEADER_SIZE = 10240;

private static final String HOST = "0.0.0.0";

private int minThreads = Config.getNumber(SERVER_CONFIG + "min_threads", MIN_THREADS);
private int maxThreads = Config.getNumber(SERVER_CONFIG + "max_threads", MAX_THREADS);
private int queueSize = Config.getNumber(SERVER_CONFIG + "max_queued", QUEUE_SIZE);
private int timeout = Config.getNumber(SERVER_CONFIG + "time_out", TIME_OUT);
private int requestHeaderSize = Config.getNumber(SERVER_CONFIG + "request_header_size", REQUEST_HEADER_SIZE);

@Override
public EmbeddedServletContainer getEmbeddedServletContainer(ServletContextInitializer... initializers) {
    init();
    WebAppContext context = new WebAppContext();
    Server server = setUpServer();
    configureWebAppContext(context, initializers);
    setupConnector(server);

    setUpHandlers(server, context);
    return getJettyEmbeddedServletContainer(server);
}

protected JettyEmbeddedServletContainer getJettyEmbeddedServletContainer(
        Server server) {
    return new JettyEmbeddedServletContainer(server, getPort() >= 0);
}

private void init(){
    try {
        Ssl ssl = new Ssl();

        String displayName = Config.getString(SERVER_CONFIG + "display_name", DISPLAY_NAME);
        Element eHttps = Config.getConfig().getElement(SERVER_CONFIG + "https");
        int httpsPort = Config.getNumber(eHttps, "port", HTTPS_PORT, SERVER_CONFIG + "https@port");
        String httpsHost = Config.getString(eHttps, "host", HOST, SERVER_CONFIG + "https@host");

        String certLocation = eHttps.attributeValue("cert_location");
        String password = eHttps.attributeValue("password");
        ssl.setEnabled(true);
        ssl.setKeyStore(certLocation);
        ssl.setKeyStorePassword(password);

        InetAddress address = InetAddress.getByName(httpsHost);
        this.setDisplayName(displayName);
        this.setPort(httpsPort);
        this.setAddress(address);
        this.setSsl(ssl);

    }
    catch (UnknownHostException e) {
        logger.error("Error occurred when config jetty: " + e.getMessage());
    }
}

private Server setUpServer() {
    QueuedThreadPool threadPool = new QueuedThreadPool(maxThreads, minThreads, timeout, new BlockingArrayQueue<Runnable>(queueSize));
    // set daemon to make sure destroy jvm when error occurred.
    threadPool.setDaemon(true);
    Server server = new Server(threadPool);
    server.setStopAtShutdown(true);
    return server;
}

private void setupConnector(Server server) {
    SslContextFactory sslContextFactory = new SslContextFactory();
    configureSsl(sslContextFactory, getSsl());
    AbstractConnector connector = getSslConnector(server, sslContextFactory);
    server.setConnectors(new Connector[] { connector });
}


private void setUpHandlers(Server server, Handler handler) {
    server.setHandler(handler);
}

private ServerConnector getSslConnector(Server server,
        SslContextFactory sslContextFactory) {
    HttpConfiguration config = new HttpConfiguration();
    config.setRequestHeaderSize(requestHeaderSize);
    config.addCustomizer(new SecureRequestCustomizer());
    HttpConnectionFactory connectionFactory = new HttpConnectionFactory(config);
    SslConnectionFactory sslConnectionFactory = new SslConnectionFactory(
            sslContextFactory, HttpVersion.HTTP_1_1.asString());
    ServerConnector serverConnector = new ServerConnector(server,
            sslConnectionFactory, connectionFactory);
    serverConnector.setPort(getPort());
    serverConnector.setHost(getAddress().getHostName());
    serverConnector.setIdleTimeout(timeout);
    return serverConnector;
}

}

问题是,当我设置 时threadPool.setDaemon(true),我的应用程序将被 shutdownhook 优雅地关闭。是什么导致这种情况发生?任何想法?

我的 spring-boot 版本是 1.3.5.RELEASE,spring-cloud-netflix 版本是 1.1.2.RELEASE。

这是我的日志的一部分。

2016-06-29 15:58:59,649 [main] INFO  [o.e.jetty.server.ServerConnector] - Started ServerConnector@14ed7ddf{SSL-HTTP/1.1}{0.0.0.0:443}
----
2016-06-29 15:58:59,653 [main] INFO  [o.s.b.c.e.j.JettyEmbeddedServletContainer] - Jetty started on port(s) 443 (ssl-http/1.1, http/1.1)
----
2016-06-29 15:58:59,661 [main] INFO  [c.f.p.ProxyServerApplication] - Started ProxyServerApplication in 10.794 seconds (JVM running for 13.182)
----
2016-06-29 15:58:59,662 [Thread-37] INFO  [o.s.b.c.e.AnnotationConfigEmbeddedWebApplicationContext] - Closing org.springframework.boot.context.embedded.AnnotationConfigEmbeddedWebApplicationContext@292b08d6: startup date [Wed Jun 29 15:58:51 CST 2016]; root of context hierarchy
----
2016-06-29 15:58:59,708 [Thread-37] INFO  [o.e.jetty.server.ServerConnector] - Stopped ServerConnector@14ed7ddf{SSL-HTTP/1.1}{0.0.0.0:443}
----
2016-06-29 15:58:59,711 [Thread-37] INFO  [oauth-server] - Destroying Spring FrameworkServlet 'dispatcherServlet'
----
2016-06-29 15:58:59,712 [Thread-37] INFO  [o.s.c.n.zuul.ZuulFilterInitializer] - Stopping filter initializer context listener
----
2016-06-29 15:58:59,716 [Thread-37] INFO  [o.e.j.server.handler.ContextHandler] - Stopped o.e.j.w.WebAppContext@5b0902b4{/,file:/C:/Users/Administrator/AppData/Local/Temp/jetty-docbase.1986886379054532101.443/,UNAVAILABLE}
----

Process finished with exit code 0
4

0 回答 0