优雅关闭 Grizzly 服务器的正确方法是什么? (内嵌球衣)
What is the proper way to gracefully shutdown a Grizzly server? (Embedded with Jersey)
我有以下代码来启动基本的嵌入式 Grizzly 服务器 运行 Jersey。
private static void startServer() {
ServerResourceConfiguration configuration = new ServerResourceConfiguration();
HttpServer server = GrizzlyHttpServerFactory.createHttpServer(
URI.create(BASE_URI),
configuration,
false,
null,
false);
server.start();
if (System.in.read() > -2) {
server.shutdownNow();
}
}
这看起来不像是停止服务器的生产级方式。
优雅关闭它的最佳做法是什么?
我猜是某种终端命令。杀掉这个进程可以,但不是很优雅。
我在这个项目上使用 Gradle 并使用 gradle run
命令运行服务器。
Gradle 任务可以完成这项工作吗?
我还看到了有关优雅地终止灰熊运输的信息:
http://grizzly-nio.net/2013/08/gracefully-terminating-a-grizzly-transport/
但我不确定我是否需要使用它。不懂怎么用
编辑:我遇到了这个 post:
这是在生产环境中终止 Http 服务器的可接受方式吗?
没有答案所以我会 post 我自己的,我用 Shutdown Hook 实现了它并且效果很好。
- 服务器将在关闭之前等待所有连接终止。
- 为了避免在连接永不终止时永远被阻塞,我们设置了一个宽限期(60 秒)
- 宽限期过后,服务器将强制终止所有连接
Here is the code for the hook to be run when the server receives a SIGINT
or SIGTERM
signal.
public class GrizzlyServerShutdownHookThread extends Thread {
public static final String THREAD_NAME = "Grizzly Server Shutdown Hook";
public static final int GRACE_PERIOD = 60;
public static final TimeUnit GRACE_PERIOD_TIME_UNIT = TimeUnit.SECONDS;
private final HttpServer server;
/**
* @param server The server to shut down
*/
public GrizzlyServerShutdownHookThread(HttpServer server) {
this.server = server;
setName(THREAD_NAME);
}
@Override
public void run() {
LOG.info("Running Grizzly Server Shutdown Hook.");
LOG.info("Shutting down server.");
GrizzlyFuture<HttpServer> future = server.shutdown(GRACE_PERIOD, GRACE_PERIOD_TIME_UNIT);
try {
LOG.info(format("Waiting for server to shut down... Grace period is %s %s", GRACE_PERIOD, GRACE_PERIOD_TIME_UNIT));
future.get();
} catch(InterruptedException | ExecutionException e) {
LOG.error("Error while shutting down server.", e);
}
LOG.info("Server stopped.");
}
}
Then I register the Hook into the RunTime object this way when I setup the server:
Runtime.getRuntime().addShutdownHook(
new GrizzlyServerShutdownHookThread(server)
);
And finally, I start the server this way:
try {
server.start();
} catch (IOException e) {
throw new RuntimeException(e);
}
// wait for a SIGINT (Ctrl+c) signal to shut down
try {
LOG.info("Press CTRL^C to exit..");
Thread.currentThread().join();
} catch(InterruptedException e) {
throw new RuntimeException(e);
}
我有以下代码来启动基本的嵌入式 Grizzly 服务器 运行 Jersey。
private static void startServer() {
ServerResourceConfiguration configuration = new ServerResourceConfiguration();
HttpServer server = GrizzlyHttpServerFactory.createHttpServer(
URI.create(BASE_URI),
configuration,
false,
null,
false);
server.start();
if (System.in.read() > -2) {
server.shutdownNow();
}
}
这看起来不像是停止服务器的生产级方式。 优雅关闭它的最佳做法是什么? 我猜是某种终端命令。杀掉这个进程可以,但不是很优雅。
我在这个项目上使用 Gradle 并使用 gradle run
命令运行服务器。
Gradle 任务可以完成这项工作吗?
我还看到了有关优雅地终止灰熊运输的信息: http://grizzly-nio.net/2013/08/gracefully-terminating-a-grizzly-transport/ 但我不确定我是否需要使用它。不懂怎么用
编辑:我遇到了这个 post: 这是在生产环境中终止 Http 服务器的可接受方式吗?
没有答案所以我会 post 我自己的,我用 Shutdown Hook 实现了它并且效果很好。
- 服务器将在关闭之前等待所有连接终止。
- 为了避免在连接永不终止时永远被阻塞,我们设置了一个宽限期(60 秒)
- 宽限期过后,服务器将强制终止所有连接
Here is the code for the hook to be run when the server receives a
SIGINT
orSIGTERM
signal.
public class GrizzlyServerShutdownHookThread extends Thread {
public static final String THREAD_NAME = "Grizzly Server Shutdown Hook";
public static final int GRACE_PERIOD = 60;
public static final TimeUnit GRACE_PERIOD_TIME_UNIT = TimeUnit.SECONDS;
private final HttpServer server;
/**
* @param server The server to shut down
*/
public GrizzlyServerShutdownHookThread(HttpServer server) {
this.server = server;
setName(THREAD_NAME);
}
@Override
public void run() {
LOG.info("Running Grizzly Server Shutdown Hook.");
LOG.info("Shutting down server.");
GrizzlyFuture<HttpServer> future = server.shutdown(GRACE_PERIOD, GRACE_PERIOD_TIME_UNIT);
try {
LOG.info(format("Waiting for server to shut down... Grace period is %s %s", GRACE_PERIOD, GRACE_PERIOD_TIME_UNIT));
future.get();
} catch(InterruptedException | ExecutionException e) {
LOG.error("Error while shutting down server.", e);
}
LOG.info("Server stopped.");
}
}
Then I register the Hook into the RunTime object this way when I setup the server:
Runtime.getRuntime().addShutdownHook(
new GrizzlyServerShutdownHookThread(server)
);
And finally, I start the server this way:
try {
server.start();
} catch (IOException e) {
throw new RuntimeException(e);
}
// wait for a SIGINT (Ctrl+c) signal to shut down
try {
LOG.info("Press CTRL^C to exit..");
Thread.currentThread().join();
} catch(InterruptedException e) {
throw new RuntimeException(e);
}