我已经编写了一个基本的嵌入式码头服务器(用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
我希望我应该从服务中获得正确的答复,但是应该从服务器中获得空的答复。在嵌入式码头服务器正常终止期间,需要什么进一步的配置才能不关闭进行中的请求?