1

我按照此处文档中的方法创建了一个带有 servlet 部署的 undertow 服务器:

http://undertow.io/documentation/servlet/deployment.html

我现在正试图停止 servlet 中的服务器和应用程序。

调用server.stop()使服务器在指定端口上不可用,但是当我server.start()再次调用时,应用程序立即可用(如果它已停止,则需要一些时间才能重新启动)。我还可以看到调用时没有释放服务器的内存server.stop。我尝试了各种组合,包括deploymentManager.undeploy()以相同的效果调用所有组合。

我已经在文档中搜索了任何线索,但结果都是空的。我想知道其他人是否有任何线索?以下是当前状态的源代码(请注意,我不是 Java 开发人员,所以会有很多花哨的东西):

package org.locee;

import io.undertow.Undertow;
import io.undertow.Undertow.Builder;
import io.undertow.Handlers;
import io.undertow.util.Headers;
import io.undertow.servlet.api.DeploymentInfo;
import io.undertow.servlet.api.DeploymentManager;
import io.undertow.server.handlers.PathHandler;
import io.undertow.server.HttpHandler;
import static io.undertow.servlet.Servlets.defaultContainer;

import javax.servlet.ServletException;

public class LoceeUndertowServer {
    private DeploymentManager deploymentManager;
    private Undertow          undertowServer;
    private DeploymentInfo    servletInfo;
    private int               port;
    private String            host;

    public LoceeUndertowServer( DeploymentInfo servletInfo, int port, String host ) {
        this.servletInfo = servletInfo;
        this.port        = port;
        this.host        = host;
    }

    public void start() throws ServletException {
        deploymentManager = defaultContainer().addDeployment( servletInfo );
        deploymentManager.deploy();

        HttpHandler httpHandler = deploymentManager.start();
        PathHandler pathHandler = Handlers.path( Handlers.redirect( "/" ) ).addPrefixPath( "/", httpHandler );
        Builder     builder     = Undertow.builder();

        builder.addHttpListener( port, host );
        builder.setHandler( pathHandler );

        undertowServer = builder.build();
        undertowServer.start();
    }

    public void shutdown() throws ServletException {
        deploymentManager.undeploy();
        defaultContainer().removeDeployment( servletInfo );
        undertowServer.stop();
    }

    public void restart() throws ServletException {
        shutdown();
        start();
    }
}
4

2 回答 2

1

您将保留所谓的对 Undertow 组件的强引用以及它们也直接引用的任何内容。引用存储在以下字段中:

private DeploymentManager deploymentManager;
private Undertow          undertowServer;
private DeploymentInfo    servletInfo;

对于 Undertow,这不是问题,而是 JVM 的功能。垃圾收集器从一组根开始(将这些视为 JVM 上的线程)并遍历对其他对象的所有引用。一旦它完成它的遍历,那么所有不可访问的对象都会被回收。这是整个过程的逻辑视图。收集时间取决于 JVM 以及世代。如果将组件放在#shutdown() 方法中,以下代码将删除对组件的引用:

   deploymentManager = null;
   undertowServer = null;
   servletInfo = null;

注意:一旦执行此操作,您将无法重新启动。

于 2015-04-12T16:22:37.653 回答
0

将一个管理端口(8090,如在 tomcat 中)放在下面:

 PathHandler path = Handlers.path()
                .addPrefixPath("/quitQuit", new QuitHandler());
        Undertow.Builder builder = Undertow.builder()
                .setHandler(path)
                .addHttpListener(8090, "0.0.0.0");
...
public class QuitHandler implements HttpHandler {
    @Override
    public void handleRequest(HttpServerExchange hse) throws Exception {
        // some log info...
          System.exit(0);
    }
}
于 2015-05-28T02:13:38.197 回答