Tyrus 端点阻止 Glassfish (Payara) 中的线程

Posted

技术标签:

【中文标题】Tyrus 端点阻止 Glassfish (Payara) 中的线程【英文标题】:Tyrus Endpoint Blocks Thread in Glassfish (Payara) 【发布时间】:2016-09-10 09:54:30 【问题描述】:

我遇到了奇怪的问题。

我的应用程序(适用于 Payara 4.1.1.163)使用 Websockets 在客户端之间发送消息。 TyrusRemoteEndpoint 用于此功能。

部署后大约 3-4 天运行良好,然后(如果这次没有部署或重新部署应用程序)tyrus 在调用函数时突然阻塞线程(甚至线程):

session.getBasicRemote().sendObject(obj);

使用 VisualVM 我已经转储了所有线程并看到以下内容:

"http-thread-pool(56)" - Thread t@209
   java.lang.Thread.State: WAITING
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for <6929ab6a> (a java.util.concurrent.CountDownLatch$Sync)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.parkAndCheckInterrupt(AbstractQueuedSynchronizer.java:836)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.doAcquireSharedInterruptibly(AbstractQueuedSynchronizer.java:997)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer.acquireSharedInterruptibly(AbstractQueuedSynchronizer.java:1304)
    at java.util.concurrent.CountDownLatch.await(CountDownLatch.java:231)
    at org.glassfish.tyrus.core.TyrusFuture.get(TyrusFuture.java:77)
    at org.glassfish.tyrus.core.TyrusRemoteEndpoint$Basic.sendObject(TyrusRemoteEndpoint.java:183)

似乎这个线程一直处于等待状态。不会为此客户端发送消息。

如果我使用同步块,它甚至会导致死锁,并且所有 http-thread-pools(涉及 websockets)都被阻塞。

什么会导致这样的问题?我该如何应对?我需要提供其他东西吗? 提前谢谢!

附:我正在使用有关线程池的默认 Payara 设置(如果有帮助的话)。

【问题讨论】:

【参考方案1】:

似乎这是 tyrus-websocket 库中的bug。

至少可以通过使用恢复应用程序来解决

getAsyncRemote()

而不是

getBasicRemote()

通过以下方式:

Future<Void> f = session.getAsyncRemote().sendObject(...)        
try 
    f.get(10, TimeUnit.SECONDS);
 catch (InterruptedException e) 
    throw new IOException(e);
 catch (ExecutionException e) 
    Throwable cause = e.getCause();
    if (cause instanceof IOException) 
        throw (IOException) cause;
     else if (cause instanceof EncodeException) 
        throw (EncodeException) cause;
     else 
        throw new IOException(e);
    
 catch (TimeoutException e) 
    throw new IOException(e);

在这种情况下,我们使用超时并至少确保我们的应用程序可以在该问题后恢复。

我还检查了this repository 以获取最新版本的 tyrus,但不能说他们已经解决了问题。可能它应该作为 Payara 或 Glassfish 的错误发布。

【讨论】:

以上是关于Tyrus 端点阻止 Glassfish (Payara) 中的线程的主要内容,如果未能解决你的问题,请参考以下文章

GlassFish 4 或 Tyrus 中的错误:每个 ByteBuffer 调用 Decoder#willDecode 两次?

无法将传入缓冲区大小设置为 Tyrus 客户端

Tyrus 服务器可以使用内部类端点吗?

tyrus websocket ssl 握手失败

收到“未收到握手响应”。关闭 websocket 后

如何以编程方式为 Tyrus WebSocket @ServerEndpoint 启用 WSS