【问题标题】:Glassfish limited to two simultaneous threads with JPA/EJB/web serviceGlassfish 仅限于两个同时使用 JPA/EJB/Web 服务的线程
【发布时间】:2010-02-18 21:46:14
【问题描述】:

我正在通过 Web 服务公开以下 EJB3 无状态会话 bean。

@Stateless
public class UserRoleFacade implements UserRoleFacadeLocal {
    @PersistenceContext(unitName = "SimpleEA-ejbPU")
    private EntityManager em;

    public int count() {
        System.out.println("thisClass=" + this.getClass().getSimpleName() + "@" + this.hashCode() + ", em=" + em);
        try {
            Thread.sleep(10000); // 10 sec
        } catch (InterruptedException ex) {
            Logger.getLogger(UserFacade.class.getName()).log(Level.SEVERE, null, ex);
        }
        return 0;
    }

}

如您所见,它并没有做太多事情——事实上,它除了在收到请求后休眠 10 秒之外什么都不做。我创建此代码作为一个实验,以了解有关 EntityManager 如何在多线程环境中工作的更多信息。

Web 服务如下所示:

@WebService(serviceName="UserRole")
public class UserRoleWebService {
    @EJB
    private UserRoleFacadeLocal ejbRef;// Add business logic below. (Right-click in editor and choose
    // "Insert Code > Add Web Service Operation")

    @WebMethod(operationName = "count")
    public int count() {
        return ejbRef.count();
    }

}

为了进行测试,我启动了 5 个浏览器,指向 Web 服务测试器,然后将它们全部触发。以下是打印出来的结果:

INFO: thisClass=UserRoleFacade@11511572, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@23961
INFO: thisClass=UserRoleFacade@32513964, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@1af5c5a
INFO: thisClass=UserRoleFacade@11511572, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@23961
INFO: thisClass=UserRoleFacade@32513964, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@1af5c5a
INFO: thisClass=UserRoleFacade@11511572, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@23961

为了进行测试,我接受了Bozho 的建议,并设置了具有 15 个线程的 JMeter。以下是打印出来的结果:

INFO: thisClass=UserRoleFacade@3869465, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@55a5d0, thread=Thread[http-thread-pool-17025-(2),10,Grizzly]
INFO: thisClass=UserRoleFacade@5558947, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@d0e940, thread=Thread[http-thread-pool-17025-(1),10,Grizzly]
INFO: thisClass=UserRoleFacade@20208512, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@635f47, thread=Thread[http-thread-pool-17025-(39),10,Grizzly]
INFO: thisClass=UserRoleFacade@23924919, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@16478c1, thread=Thread[http-thread-pool-17025-(41),10,Grizzly]
INFO: thisClass=UserRoleFacade@6172173, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@121691b, thread=Thread[http-thread-pool-17025-(40),10,Grizzly]
INFO: thisClass=UserRoleFacade@3869465, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@55a5d0, thread=Thread[http-thread-pool-17025-(2),10,Grizzly]
INFO: thisClass=UserRoleFacade@5558947, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@d0e940, thread=Thread[http-thread-pool-17025-(1),10,Grizzly]
INFO: thisClass=UserRoleFacade@23924919, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@16478c1, thread=Thread[http-thread-pool-17025-(39),10,Grizzly]
INFO: thisClass=UserRoleFacade@20208512, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@635f47, thread=Thread[http-thread-pool-17025-(40),10,Grizzly]
INFO: thisClass=UserRoleFacade@6172173, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@121691b, thread=Thread[http-thread-pool-17025-(41),10,Grizzly]
INFO: thisClass=UserRoleFacade@3869465, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@55a5d0, thread=Thread[http-thread-pool-17025-(2),10,Grizzly]
INFO: thisClass=UserRoleFacade@5558947, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@d0e940, thread=Thread[http-thread-pool-17025-(1),10,Grizzly]
INFO: thisClass=UserRoleFacade@23924919, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@16478c1, thread=Thread[http-thread-pool-17025-(39),10,Grizzly]
INFO: thisClass=UserRoleFacade@6172173, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@121691b, thread=Thread[http-thread-pool-17025-(41),10,Grizzly]
INFO: thisClass=UserRoleFacade@20208512, em=com.sun.enterprise.container.common.impl.EntityManagerWrapper@635f47, thread=Thread[http-thread-pool-17025-(40),10,Grizzly]

正如你所看到的(以及我从浏览器中看到的)是只有 2 只有 5 个线程同时运行。 EJB 和 EntityManager 的实例看起来都可能在某个地方受到限制。那是哪里?

在 Glassfish 应用服务器上,我的设置如下:

  • 连接池:8 个初始连接,最大 32 个
  • ejb 容器:初始 0 个,最大 32 个

我猜这些没问题。 EnitiyManager 是否有设置?我还应该看什么?

【问题讨论】:

    标签: java web-services jpa jakarta-ee ejb-3.0


    【解决方案1】:

    在管理控制台中检查 configuration>thread-pools>thread-pool#min-thread-pool-size(应该是 2)。但这只是一个最小值,当然不是最大值。

    【讨论】:

    • 谢谢!在我根据@Bohzo 的建议进行了一些适当的测试设置并注意到一个 5 螺纹帽之后,我查看了这个设置,发现它的上限为 5(最小​​值确实是 2)。增加线程数后,它按预期工作。
    • 这个答案拯救了我。我正在做一些长时间的轮询,我会在 2 次请求后发现其他一切都会挂起。还有两件事我不明白。 MIN 是 2,但默认最大值是 5。为什么我在 2 时被阻止?它不应该增长游泳池吗?二、为什么默认是2?这似乎小得不合理。无论如何。
    【解决方案2】:

    我怀疑有这样的限制。也许这项工作很快就完成了,加上连接延迟,因此实体管理器被重用了。

    为了做出更好的基准测试,使用JMeter - 在 X 秒内触发 15 个请求,并共享输出。 (this article 为使用 JMeter 提供了一个开始。但无论如何它都非常简单)

    【讨论】:

    • 谢谢!我接受了您的建议并将输出作为问题的更新发布。现在看来我被限制在 5 个线程...
    • 您最初的假设确实是正确的。我查看了@Pascal 建议的设置,发现这是限制我的连接数的设置。但是,如果没有您的 JMeter 建议,我不会走那么远。非常感谢!
    猜你喜欢
    • 1970-01-01
    • 2012-06-20
    • 1970-01-01
    • 1970-01-01
    • 2011-07-26
    • 1970-01-01
    • 2011-02-24
    • 1970-01-01
    • 2016-07-20
    相关资源
    最近更新 更多