JDBC 连接是否应该与 netstat 网络连接相匹配?

Are JDBC connections supposed to match the netstat network connections?

我们有一个 Tomcat6/Hibernate 3.x/Postgres 应用程序,我 无助地超出了我的深度 有点不清楚 "connection" 在应用程序服务器和数据库之间,至少就 JDBC 而言。

从表面上看,我们使用的是连接池 (Tomcat JDBC),它在启动时打开 10 个连接。 Netstat 似乎证实了这一点:

netstat -nato | grep 5432
::ffff:192.168.42.11:5432   ESTABLISHED off (0.00/0/0)
::ffff:192.168.42.11:5432   ESTABLISHED off (0.00/0/0)
::ffff:192.168.42.11:5432   ESTABLISHED off (0.00/0/0)
::ffff:192.168.42.11:5432   ESTABLISHED off (0.00/0/0)
::ffff:192.168.42.11:5432   ESTABLISHED off (0.00/0/0)
::ffff:192.168.42.11:5432   ESTABLISHED off (0.00/0/0)
::ffff:192.168.42.11:5432   ESTABLISHED off (0.00/0/0)
::ffff:192.168.42.11:5432   ESTABLISHED off (0.00/0/0)
::ffff:192.168.42.11:5432   ESTABLISHED off (0.00/0/0)
::ffff:192.168.42.11:5432   ESTABLISHED off (0.00/0/0)

但是那些连接始终保持在 'off' 状态。当我将 JDBC 的 Hibernate 日志设置为 DEBUG 时,我看到大量 openConnection()closeConnection() 调用(一个简单的网页超过 100 个),但 netstat 的输出保持不变.

那么 JDBC 和网络连接不是按 1:1 比率创建的吗?这只是连接池实际工作的证据吗?

这就是 connection pooling works. The pool opens N number of physical database connections and when the application acquires a connection, it will get a JDBC Connection 代理的方式,而不是实际的驱动程序连接对象。

当应用事务完成后,Connection.close()方法被调用。代理将拦截 close 方法并简单地 return 连接对象到池中,而不是实际关闭物理连接。

你看到这么多openConnection()closeConnection()方法的原因可以解释如下:

  • 您正在使用 JTA,它要求 aggressive connection release 以每个语句为基础。
  • 您没有将您的操作包装在单个@Transactional 服务方法中,并且 Hibernate 默认为自动提交,因此每个语句都将 运行 在其自己的特定事务中(并且每个语句实际上都需要一个连接acquire/release循环)。
  • 您大量使用 Ajax,因此加载首页不仅仅是一个 HTTP 请求。您发出的异步请求越多,需要的事务就越多,您对连接池的压力就越大。

为了监控和调整连接池,我建议您开始使用 FlexyPool