我正在运行一项操作,该操作涉及对glassfish上托管的服务的大量远程EJB调用。
客户端和服务器之间存在高延迟,因此我尝试通过多线程处理请求来加速操作。
不幸的是,我似乎没有通过多线程处理请求来获得任何速度提升 - 相反 - 我的线程请求正在排队。
我的问题是我无法弄清楚他们排队的原因。
我检查了服务器上的线程池配置 - 并在运行时检查了它 - 我在服务器上看到相应数量的线程,我在客户端进行EJB调用时拥有的线程数。这些线程中的大多数都是空闲的,但大部分时间都是空闲的 - 请求根本就没有到达。
我觉得我的呼叫在客户端被阻止 - 从我在服务器上看到的 - 从查看jVisualVM中的线程 - 以及查看服务器上的资源使用情况(几乎空闲)。
在客户端上,我为每个线程创建一个完整的,新的InitialContext对象/连接。
在客户端上,我看到我的大多数线程都在corba中被阻止:
"p: default-threadpool; w: 29" daemon prio=10 tid=0x00007f18b4001000 nid=0x608f in Object.wait() [0x00007f19ae32b000]
java.lang.Thread.State: WAITING (on object monitor)
at java.lang.Object.wait(Native Method)
- waiting on <0x00000000f2ef5388> (a java.util.LinkedList)
at java.lang.Object.wait(Object.java:503)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.resumeOptimizedReadProcessing(CorbaMessageMediatorImpl.java:791)
- locked <0x00000000f2ef5388> (a java.util.LinkedList)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.setWorkThenReadOrResumeOptimizedRead(CorbaMessageMediatorImpl.java:869)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleInput(CorbaMessageMediatorImpl.java:1326)
at com.sun.corba.ee.impl.protocol.giopmsgheaders.FragmentMessage_1_2.callback(FragmentMessage_1_2.java:122)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.handleRequest(CorbaMessageMediatorImpl.java:742)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.dispatch(CorbaMessageMediatorImpl.java:539)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.doWork(CorbaMessageMediatorImpl.java:2324)
at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.performWork(ThreadPoolImpl.java:497)
at com.sun.corba.ee.impl.orbutil.threadpool.ThreadPoolImpl$WorkerThread.run(ThreadPoolImpl.java:540)
我的帖子被阻止
"Pool-27" daemon prio=10 tid=0x00007f19b403c800 nid=0x4ef8 waiting on condition [0x00007f19ac70e000]
java.lang.Thread.State: TIMED_WAITING (parking)
at sun.misc.Unsafe.park(Native Method)
- parking to wait for <0x00000000f2f66078> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:226)
at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2082)
at com.sun.corba.ee.impl.transport.CorbaResponseWaitingRoomImpl.waitForResponse(CorbaResponseWaitingRoomImpl.java:173)
at com.sun.corba.ee.impl.transport.SocketOrChannelConnectionImpl.waitForResponse(SocketOrChannelConnectionImpl.java:1021)
at com.sun.corba.ee.impl.protocol.CorbaMessageMediatorImpl.waitForResponse(CorbaMessageMediatorImpl.java:279)
at com.sun.corba.ee.impl.protocol.CorbaClientRequestDispatcherImpl.marshalingComplete1(CorbaClientRequestDispatcherImpl.java:407)
at com.sun.corba.ee.impl.protocol.CorbaClientRequestDispatcherImpl.marshalingComplete(CorbaClientRequestDispatcherImpl.java:368)
at com.sun.corba.ee.impl.protocol.CorbaClientDelegateImpl.invoke(CorbaClientDelegateImpl.java:273)
at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.privateInvoke(StubInvocationHandlerImpl.java:200)
at com.sun.corba.ee.impl.presentation.rmi.StubInvocationHandlerImpl.invoke(StubInvocationHandlerImpl.java:152)
at com.sun.corba.ee.impl.presentation.rmi.codegen.CodegenStubBase.invoke(CodegenStubBase.java:227)
其他让我烦恼的是,无论我在客户端上运行了多少线程 - 我只得到一个 - 有时是2 - &#39; RMI TCP连接&#39;线程。但我不确定这是否涉及EJB远程处理。
为什么/这些远程调用阻止了我的客户端线程?
请注意,这不是带宽问题 - 传输的数据量很小 - 但存在高延迟。因此,并行提出更多请求应该会给我一个改进。相反 - 我的整体时间保持不变 - 但是个别请求从500毫秒变为5000毫秒,例如,当我增加客户端线程数时。
任何超过2或3个线程的东西都不会对整体时间产生任何影响。
如果我将延迟从图片中删除,通过在与GlassFish服务器相同的系统上运行本地相同的进程,性能如预期的那样 - 太快甚至无法调试 - 因此毫无疑问服务器能够处理工作量。
我似乎无法从客户端并行发出请求。
答案 0 :(得分:0)
检查EJB的类型。如果调用相同的Stateful或Singleton EJB,则会同步调用 - 默认情况下,一次只允许单次调用,无论您调用相同的方法还是不同的方法。对于无状态EJB,情况并非如此,但如果池耗尽,则可能会阻止调用 - 检查服务器上EJB池的大小并增加它。
使用Stateful,您无法更改行为(请参阅this answer,但您可以为每个远程客户端实例化一个新EJB。对于Singleton,您应该考虑adjusting concurrency management以允许更多吞吐量。