【问题标题】:EJB Client freezes on getting the results from a Wildfly 25 or 26EJB 客户端在从 Wildfly 25 或 26 获取结果时冻结
【发布时间】:2022-01-23 06:28:21
【问题描述】:

我目前正在努力处理针对 Wildfly 25 或 26 的 EJB 远程调用。 相同的客户端应用程序适用于 Widfly 10、13、16、20,在某种程度上也适用于 Wildfly 25 或 26。 问题开始于 EJB 调用的返回对象大小超过某个限制,该限制似乎有时会改变。示例:我制作了一个测试 EJB 方法,它返回我作为参数提供的相同字符串。大多数情况下,如果字符串的长度超过 ~65.000 个字符,Wildfly EJB 客户端会挂起读取结果。无论如何,有时我也经历过客户端冻结超过该限制。在我的客户端中,我注册了一个 EJB 调用拦截器,我看到调用 EJB-context.getResult() 时调用冻结。在服务器端,同样基于服务器端拦截器,我看到调用已完成,但显然在通过 EJB 客户端接收返回值时出现了问题。 这是挂起线程的堆栈跟踪:

    "main@1" prio=5 tid=0x1 nid=NA waiting
java.lang.Thread.State: WAITING
  at java.lang.Object.wait(Object.java:-1)
  at java.lang.Object.wait(Object.java:502)
  at org.wildfly.httpclient.common.WildflyClientInputStream.read(WildflyClientInputStream.java:147)
  at java.io.FilterInputStream.read(FilterInputStream.java:133)
  at org.jboss.marshalling.SimpleDataInput.read(SimpleDataInput.java:111)
  at org.jboss.marshalling.UTFUtils.readUTFBytes(UTFUtils.java:151)
  at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:314)
  at org.jboss.marshalling.river.RiverUnmarshaller.doReadObject(RiverUnmarshaller.java:231)
  at org.jboss.marshalling.AbstractObjectInput.readObject(AbstractObjectInput.java:41)
  at org.wildfly.httpclient.ejb.HttpEJBReceiver$2.getResult(HttpEJBReceiver.java:207)
  at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:620)
  at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:551)
  at org.jboss.ejb.protocol.remote.RemotingEJBClientInterceptor.handleInvocationResult(RemotingEJBClientInterceptor.java:57)
  at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:622)
  at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:551)
  at org.jboss.ejb.client.TransactionPostDiscoveryInterceptor.handleInvocationResult(TransactionPostDiscoveryInterceptor.java:148)
  at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:622)
  at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:551)
  at org.jboss.ejb.client.DiscoveryEJBClientInterceptor.handleInvocationResult(DiscoveryEJBClientInterceptor.java:130)
  at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:622)
  at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:551)
  at org.jboss.ejb.client.NamingEJBClientInterceptor.handleInvocationResult(NamingEJBClientInterceptor.java:87)
  at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:622)
  at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:551)
  at org.jboss.ejb.client.AuthenticationContextEJBClientInterceptor$$Lambda$94.871790326.get(Unknown Source:-1)
  at org.jboss.ejb.client.AuthenticationContextEJBClientInterceptor.call(AuthenticationContextEJBClientInterceptor.java:59)
  at org.jboss.ejb.client.AuthenticationContextEJBClientInterceptor.handleInvocationResult(AuthenticationContextEJBClientInterceptor.java:52)
  at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:622)
  at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:551)
  at com.ge.hac.ca.common.util.CommonClientInvocationInterceptor.handleInvocationResult(CommonClientInvocationInterceptor.java:196)
  at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:622)
  at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:551)
  at org.jboss.ejb.client.TransactionInterceptor.handleInvocationResult(TransactionInterceptor.java:212)
  at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:622)
  at org.jboss.ejb.client.EJBClientInvocationContext.getResult(EJBClientInvocationContext.java:551)
  at org.jboss.ejb.client.EJBClientInvocationContext.awaitResponse(EJBClientInvocationContext.java:1003)
  at org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:182)
  at org.jboss.ejb.client.EJBInvocationHandler.invoke(EJBInvocationHandler.java:116)
  at com.sun.proxy.$Proxy4.loopback(Unknown Source:-1)
  at com.ge.hac.ca.perf.connection.TestConnectionToWildfly.checkEJBInvocation_LoggerService(TestConnectionToWildfly.java:225)
  at com.ge.hac.ca.perf.connection.TestConnectionToWildfly.executeEJBIterations(TestConnectionToWildfly.java:191)
  at com.ge.hac.ca.perf.connection.TestConnectionToWildfly.main(TestConnectionToWildfly.java:401)

我正在使用 Amazon Corretto jdk1.8.0_292。

有没有人遇到过类似的问题,如果有,如何解决?

【问题讨论】:

    标签: ejb wildfly freeze


    【解决方案1】:

    带有大量结果对象(即字符串 >= 64 KB)的 EJB 调用不适用于 Wildfly 25 或 26,因为我现在必须使用 HTTP 协议,而不是“远程处理”我多年前使用的协议。 具体来说,HTTP/2 实现不起作用,但 HTTP/1 似乎起作用。

    说明: 我已经检查/调试了 Wildfly 客户端代码,我认为 HTTP/2 协议实现的服务器和客户端代码都存在一些错误。

    第一个错误:服务器在数据流中间突然发送(主要是在更大的对象上)FRAME_TYPE_RST_STREAM(参见 io.undertow.protocols.http2.Http2FrameHeaderParser:191 --> type = header[3] & 0xff; ), 它将流标记为已损坏(请参阅 io.undertow.server.protocol.framed.AbstractFramedStreamSourceChannel:684 --> state |= STATE_STREAM_BROKEN;) 然后在客户端内的所有流读取上导致“ClosedChannelExceptions”(参见 org.wildfly.httpclient.common.WildflyClientInputStream:58 --> int res = streamSourceChannel.read(pooled.getBuffer());) 我没有调试服务器端代码,所以我不知道为什么服务器会突然在一些巨大的对象上发送一个“重置流”。有时,同一个巨大的对象会毫无问题地传输给客户端。使用 HTTP/1 时不会发生这种情况,因此它不会是网络问题。

    第二个错误(由上述重置流引发):客户端无法正确处理接收到的重置流引发的“ClosedChannelExceptions”,因为它冻结了整个通信。 客户端不断从通道中读取数据,每次读取后都会调用其锁定对象上的 wait(0)(参见 org.wildfly.httpclient.common.WildflyClientInputStream:147 --> lock.wait();) 通常通过调用同一锁定对象的 notifyAll() 来继续等待(0)(在 ClosedChannelExceptions 的情况下,它是 org.wildfly.httpclient.common.WildflyClientInputStream:94 --> lock.notifyAll(); 不幸的是,在最后一次读取并因此最后一次调用 wait(0) 之后,不再调用 notifyAll(),因此 EJB 客户端调用永远冻结。在我看来,这在任何情况下都不应该发生。

    我找到的解决方案是,但我对此并不满意,即禁用服务器上的 HTTP/2 协议并改用 HTTP/1。 Standalone-full.xml --> enable-http2="false" />

    现在通过 HTTP/1 协议进行 EJB 调用也适用于大对象。

    上面提到的带有行号的类都取自 Wildlfy 26.0.0 Client jar:

    我希望一些 Wildfly 专家会阅读此内容并做出反应。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2014-08-10
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-04-23
      • 2013-01-14
      • 1970-01-01
      相关资源
      最近更新 更多