【问题标题】:Jersey resource @PreDestroy not getting called when Grizzley server is shut down当 Grizzley 服务器关闭时,泽西资源 @PreDestroy 没有被调用
【发布时间】:2018-10-30 14:57:43
【问题描述】:

我正在运行一个简单的 Jersey/Grizzly HTTP 服务器,它有一个资源来处理服务器发送的事件

该资源需要手动处理 Timer 实例以向所有连接的 SSE 客户端发送一些保持活动的数据,因此我使用 @PostConstruct@PreDestroy 注释来构造和取消该计时器(及其背景线程)。

该应用程序是一个简单的控制台应用程序,并没有嵌入到任何容器环境中,例如 Tomcat。启动 Web 服务器后,它会等待一个简单的 System.in.read(),然后通过在 Grizzly HTTP 服务器实例上调用 shutdownNow() 再次关闭服务器。

连接到 SSE 资源时,实例化资源类并启动计时器。与服务器断开连接后,经过短暂的延迟后,资源再次被销毁,一切正常。

但由于 SSE 资源的性质,客户端可能会无休止地连接,因此也会在内部保留资源实例。

如果我现在尝试在客户端连接时通过调用 shutdownNow() 来关闭服务器,服务器实例会正确关闭,但不会调用任何活动资源的 @PreDestroy 方法。这会导致我的资源与 Timer 实例保持不变,并且由于计时器仍然处于活动状态,这反过来会保持 java 进程运行,即使 HTTP 服务器已经关闭。

有什么方法可以检索所有当前活动的资源实例,以便我可以在关闭 HTTP 服务器之前手动调用它们各自的销毁方法? 或者这可能是资源实例管理中的错误灰熊服务器?

使用的版本是:

  • jersey-container-grizzly2-http:2.27
  • grizzly-http-server: 2.4.0(来自上面的依赖)

这是代码的简化版本:

public class ServerSentEventResource {
    @Context
    private Sse sse;
    private volatile SseBroadcaster broadcaster;
    private final Timer timer = new Timer();

    @PostConstruct
    public void init() {
        broadcaster = sse.newBroadcaster();
        final TimerTask task = new TimerTask() {
            // ...
        };
        timer.scheduleAtFixedRate(task, 0, 1000);
    }

    @PreDestroy
    public void destroy() {
        timer.cancel();
        broadcaster.close();
    }

    @GET
    @Produces(SseFeature.SERVER_SENT_EVENTS)
    public void get(@Context final SseEventSink eventSink) {
        broadcaster.register(eventSink);
    }
}

public static void main(final String[] args) {
    ResourceConfig resourceConfig = new ResourceConfig();
    resourceConfig.register(ServerSentEventResource.class);

    HttpServer server = GrizzlyHttpServerFactory.createHttpServer(URI.create("0.0.0.0:8888"), resourceConfig);
    System.in.read();
    server.shutdownNow();

    // At this point there is still the resource instance around, keeping the timer running, thus keeping the JVM running :(
}

【问题讨论】:

    标签: jersey-2.0 server-sent-events grizzly


    【解决方案1】:

    我遇到了同样的问题。我能够通过在实际关闭服务器之前删除默认网络侦听器来解决此问题...

    httpServer.removeListener("grizzly");
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-26
      • 1970-01-01
      • 1970-01-01
      • 2013-02-10
      • 1970-01-01
      相关资源
      最近更新 更多