优雅关闭Grizzly服务器的正确方法是什么? (嵌入泽西岛)

时间:2017-06-15 16:12:08

标签: java server jersey shutdown grizzly

我有以下代码来启动与Jersey一起运行的基本嵌入式Grizzly服务器。

  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/ 但我不确定我是否需要使用它。我不明白如何使用它。

编辑:我遇到过这篇文章: https://stackoverflow.com/a/15391081/3982755 这是在生产环境中终止Http服务器的可接受方式吗?

1 个答案:

答案 0 :(得分:1)

没有答案所以我会发布自己的答案,我用Shutdown Hook实现它并且效果非常好。

  • 服务器将在关闭之前等待所有连接终止。
  • 为了避免在连接永远不会终止时被阻止,我们设置一个宽限期(60秒)
  • 在宽限期后,服务器将强制终止所有连接
  

以下是服务器收到dput() output: structure(list(group = structure(c(1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L, 1L, 2L, 3L, 4L), .Label = c("A", "B", "C", "D"), class = "factor"), correct_per = c(90.4761904761905, 100, 100, 87.5, 83.3333333333333, 90.9090909090909, 84.6153846153846, 87.5, 80.9523809523809, 88.6363636363636, 100, 70.8333333333333, 63.4146341463415, 76.7441860465116, 76.9230769230769, 62.5), nr_correct = c(38L, 44L, 26L, 21L, 35L, 40L, 22L, 21L, 34L, 39L, 26L, 17L, 26L, 33L, 20L, 15L), nr_incorrect = c(4L, 0L, 0L, 3L, 7L, 4L, 4L, 3L, 8L, 5L, 0L, 7L, 15L, 10L, 6L, 9L), length = c(42L, 44L, 26L, 24L, 42L, 44L, 26L, 24L, 42L, 44L, 26L, 24L, 41L, 43L, 26L, 24L), qid = c("8", "8", "8", "8", "9", "9", "9", "9", "10", "10", "10", "10", "11", "11", "11", "11")), .Names = c("group", "correct_per", "nr_correct", "nr_incorrect", "length", "qid"), row.names = c(NA, -16L), class = c("tbl_df", "tbl", "data.frame")) save to file all_Q <- dget(filename) ggplot(all_Q, aes(x=qid, y=correct_per, fill=group)) + geom_bar(stat="identity", position="dodge") + scale_x_discrete(limits = as.character(11:8)) + coord_flip() SIGINT信号时要运行的挂钩的代码。

SIGTERM
  

然后我在设置服务器时以这种方式将Hook注册到RunTime对象中:

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.");
  }
}
  

最后,我以这种方式启动服务器:

Runtime.getRuntime().addShutdownHook(
    new GrizzlyServerShutdownHookThread(server)
);