Wildfly 连接池因已取消的 HTTP 请求而耗尽
Wildfly connection pool exhausted on canceled HTTP requests
我在带有 RESTeasy 和 Hibernate 的 Wildfly 10 上有一个 Java EE 应用程序 运行。该应用程序非常简单,它有实体、DAO 和资源:
@Entity
public class MyEntity {
// ...
}
@Stateless
public class MyDAO {
@PersistenceContext
private EntityManager em;
public List<MyEntity> list() {
return this.em.createQuery("select e from MyEntity e", MyEntity.class).getResultList();
}
}
@Path("/resource")
public class MyResource {
@Inject
private MyDAO dao;
@GET
public List<MyEntity> get() {
return this.dao.list();
}
}
所以我不直接使用任何 JDBC 连接,我将它全部委托给 JPA。
问题是:无论我的连接池有多大,它最终都会耗尽。由于数据源连接是在无状态 bean 中处理的,AFAIK 连接 opening/closing 应该无缝处理。
调查此连接泄漏,我发现我有很多
ERROR [io.undertow.request] (default task-25) UT005023: Exception handling request to /resource: org.jboss.resteasy.spi.UnhandledException: RESTEASY003770: Response is committed, can't handle exception
...
Caused by: java.io.IOException: Broken pipe
异常,由客户端取消的 HTTP 请求引起。这些异常会导致连接泄漏吗?我希望不会,因为客户端操作不应该耗尽服务器连接池。
问题是:问题可能出在取消的 HTTP 请求上,我如何指示 Undertow/RESTeasy/Hibernate 处理该请求并干净地退出?还有什么地方可能泄漏,或者我如何调查才能找出答案?
更新 1
[已删除]
更新 2
上次更新(取消的 HTTP 请求)具有误导性:进一步的测试表明这种情况在其他情况下是如何发生的,例如计划任务(Java EE @Schedule
)和事件观察者(Java EE @Observe
).
更新后的问题是:当仅使用 JPA 访问数据库时,什么会阻止释放连接?
终于发现它是什么了:Java 惰性集合上的 8 个并行流。简单地不要将并行流用于 JPA 关系的集合,因为它可能在流处理期间使用来自池的多个连接,但在收集结果时只有一个连接 returned 到池而其他连接失败并显示 尝试return同一个连接两次,最终耗尽池。
我在带有 RESTeasy 和 Hibernate 的 Wildfly 10 上有一个 Java EE 应用程序 运行。该应用程序非常简单,它有实体、DAO 和资源:
@Entity
public class MyEntity {
// ...
}
@Stateless
public class MyDAO {
@PersistenceContext
private EntityManager em;
public List<MyEntity> list() {
return this.em.createQuery("select e from MyEntity e", MyEntity.class).getResultList();
}
}
@Path("/resource")
public class MyResource {
@Inject
private MyDAO dao;
@GET
public List<MyEntity> get() {
return this.dao.list();
}
}
所以我不直接使用任何 JDBC 连接,我将它全部委托给 JPA。
问题是:无论我的连接池有多大,它最终都会耗尽。由于数据源连接是在无状态 bean 中处理的,AFAIK 连接 opening/closing 应该无缝处理。
调查此连接泄漏,我发现我有很多
ERROR [io.undertow.request] (default task-25) UT005023: Exception handling request to /resource: org.jboss.resteasy.spi.UnhandledException: RESTEASY003770: Response is committed, can't handle exception
...
Caused by: java.io.IOException: Broken pipe
异常,由客户端取消的 HTTP 请求引起。这些异常会导致连接泄漏吗?我希望不会,因为客户端操作不应该耗尽服务器连接池。
问题是:问题可能出在取消的 HTTP 请求上,我如何指示 Undertow/RESTeasy/Hibernate 处理该请求并干净地退出?还有什么地方可能泄漏,或者我如何调查才能找出答案?
更新 1
[已删除]
更新 2
上次更新(取消的 HTTP 请求)具有误导性:进一步的测试表明这种情况在其他情况下是如何发生的,例如计划任务(Java EE @Schedule
)和事件观察者(Java EE @Observe
).
更新后的问题是:当仅使用 JPA 访问数据库时,什么会阻止释放连接?
终于发现它是什么了:Java 惰性集合上的 8 个并行流。简单地不要将并行流用于 JPA 关系的集合,因为它可能在流处理期间使用来自池的多个连接,但在收集结果时只有一个连接 returned 到池而其他连接失败并显示 尝试return同一个连接两次,最终耗尽池。