优雅终止过程中嵌入式码头关闭开放式连接

时间:2019-05-25 19:15:12

标签: java curl jersey jetty embedded-jetty

我已经编写了一个基本的嵌入式码头服务器(用jersey定义端点),并且需要它优雅地终止(以响应SIGINT)。我希望所有进行中的请求完成处理并将结果返回给请求者(直到超时),同时不接受任何新的连接/请求。

我目前看到的行为是正在进行中的请求已正确完成,但是与客户端的连接已终止(因此它们不会收到对其请求的响应)。

在创建我的Server实例时,我将setStopAtShutdown设置为true并为setStopTimeout设置了一个值。我还配置了StatisticsHandler。从我的文档中可以看出,这是启用正常终止的条件。

这是我的码头服务器设置:

// For additional Jetty configuration options see:
// https://www.eclipse.org/jetty/documentation/current/embedding-jetty.html#_like_jetty_xml
public static Server createServer(
    int port, int shutdownGracePeriodMillis, int httpServerThreads, int httpIdleTimeoutMillis) {
    // Create server
    QueuedThreadPool threadPool = new QueuedThreadPool();
    threadPool.setMaxThreads(httpServerThreads);
    Server server = new Server(threadPool);
    HttpConfiguration config = new HttpConfiguration();
    ServerConnector http = new ServerConnector(server, new HttpConnectionFactory(config));
    http.setPort(port);
    http.setIdleTimeout(httpIdleTimeoutMillis);
    server.addConnector(http);

    // Enable StatisticsHandler (required for graceful termination)
    StatisticsHandler stats = new StatisticsHandler();
    stats.setHandler(server.getHandler());
    server.setHandler(stats);
    ServerConnectionStatistics.addToAllConnectors(server);

    // Configure graceful termination
    server.setStopAtShutdown(true);
    server.setStopTimeout(shutdownGracePeriodMillis);

    // Associate Jersey with Jetty
    JettyHttpContainer container =
        ContainerFactory.createContainer(JettyHttpContainer.class, new AppResourceConfig());
    server.setHandler(container);

    return server;
}

这是我的球衣资源。它使用Thread.sleep模拟一些长时间运行的请求,该请求需要在服务器关闭之前完成。

@POST
@Consumes("application/json")
@Produces(MediaType.TEXT_PLAIN)
public String testEndpoint() {
    for(int i = 0; i < 4; i++) {
        try {
            logger.info("Number: " + i);
            Thread.sleep(5000);
        } catch (Exception e) { }
    }

    logger.info("Request completed!");

    return "Hello, world!\n";
}

我运行服务器并发出以下curl命令

curl -v --header "Content-Type: application/json" \
  --request POST \
  --data '' \
  http://localhost:4200/testEndpoint

当此请求仍在等待响应时,当我向服务器进程发送SIGINT时,我会在服务器上看到该信息:

INFO  c.a.a.s.resources.Resource - Number: 0
INFO  c.a.a.s.resources.Resource - Number: 1
^C {{NOTE: SIGINT issued here}}
[Thread-1] INFO  o.e.jetty.server.AbstractConnector - Stopped ServerConnector@32c726ee{HTTP/1.1,[http/1.1]}{0.0.0.0:4200}
INFO  c.a.a.s.resources.AuctionResource - Number: 2
INFO  c.a.a.s.resources.AuctionResource - Number: 3
INFO  c.a.a.s.resources.AuctionResource - Request completed!

我们可以从服务器日志中看到请求已正确完成。 curl命令永远不会收到“ Hello,world!”的响应。不过(在常规的不间断请求中会这样做)。

curl输出如下:

*   Trying ::1...
* TCP_NODELAY set
* Connected to localhost (::1) port 4200 (#0)
> POST /testEndpoint HTTP/1.1
> Host: localhost:4200
> User-Agent: curl/7.54.0
> Accept: */*
> Content-Type: application/json
> Content-Length: 0
> 
* Empty reply from server
* Connection #0 to host localhost left intact
curl: (52) Empty reply from server

我希望我应该从服务中获得正确的答复,但是应该从服务器中获得空的答复。在嵌入式码头服务器正常终止期间,需要什么进一步的配置才能不关闭进行中的请求?

0 个答案:

没有答案