gpt4 book ai didi

Java 连接池不限制打开到数据库服务器的 TCP 连接数

转载 作者:塔克拉玛干 更新时间:2023-11-02 19:16:13 35 4
gpt4 key购买 nike

我使用 Hibernate 属性来定义连接池大小,以及 LocalSessionFactoryBeanDriverManagerDataSource 来创建 org.hibernate.SessionFactory 我观察到 1000 个 TCP 连接打开到数据库服务器,而不是我预期的连接池大小上限 100。

设置连接 Hibernate 池的代码如下所示。请注意最大大小为 100,但是我从我的工作站观察到 1000 个到数据库服务器的连接 - 我在 Windows 机器上使用 TCPView 连接到由 Vagrant (VirtualBox) 管理的 Centos OS VM 上的 MariabDB 实例

Properties hibernateProperties = new Properties();
hibernateProperties.put("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect");
hibernateProperties.put("hibernate.show_sql", false);
hibernateProperties.put("hibernate.generate_statistics", false);
hibernateProperties.put("hibernate.hbm2ddl.auto", "update");
hibernateProperties.put("hibernate.use_sql_comments", false);

hibernateProperties.put("hibernate.c3p0.min_size", 10);
hibernateProperties.put("hibernate.c3p0.max_size", 100);
hibernateProperties.put("hibernate.c3p0.timeout", 1500);
hibernateProperties.put("hibernate.c3p0.max_statements", 5000);
hibernateProperties.put("hibernate.c3p0.idle_test_period", 60);

LocalSessionFactoryBean localSessionFactoryBean = new LocalSessionFactoryBean();
localSessionFactoryBean.setDataSource(dataSource);
localSessionFactoryBean.setHibernateProperties(hibernateProperties);
localSessionFactoryBean.setMappingResources("job.persistence.xml");

我希望看到这些连接在 100 时达到最大值并被重新用于以后的循环执行,但我观察到超过 1000 个连接在 TIME_WAIT 中等待了大约一分钟,然后才关闭。以下是 TCPView 的输出示例:

[System Process]    0   TCP localhost   62794   192.168.98.102  3306    TIME_WAIT                                       
[System Process] 0 TCP localhost 62796 192.168.98.102 3306 TIME_WAIT
[System Process] 0 TCP localhost 62797 192.168.98.102 3306 TIME_WAIT
[System Process] 0 TCP localhost 62795 192.168.98.102 3306 TIME_WAIT
[System Process] 0 TCP localhost 62798 192.168.98.102 3306 TIME_WAIT
[System Process] 0 TCP localhost 62801 192.168.98.102 3306 TIME_WAIT

我显然做错了什么,但不确定是什么。我正在使用 Spring 来管理提供数据访问逻辑的 DAO。 DAO 注册为原型(prototype) Spring 作用域,而 Singleton SessionFactory 像这样注入(inject)到 DAO 中:

@Bean(name="jobDao")
@Scope(SpringBeanScope.Prototype)
public JobDao jobDao(SessionFactory jobSessionFactory) { //...}

在 DAO 中,我调用 sessionFactory.getCurrentSession() 来访问数据库 session 。以下是通用 DAO 基础的摘录,演示了这一点:

protected Session currentSession() {
return sessionFactory.getCurrentSession();
}

@Transactional
@Override
public void Add(TEntity entity) {

currentSession().save(entity);
}

有谁知道当连接池限制为 100 时为什么会打开这么多 TCP 连接?

更新

由于此问题出现在 Windows 开发机器上,我将一个小型 .NET 控制台应用程序放在一起,该应用程序使用并行 for 循环来执行一个简单的 SQL 选择语句,最大线程数为 64,每次都创建一个新连接:

public void Test()
{
ParallelOptions options = new ParallelOptions();
options.MaxDegreeOfParallelism = 64;

Parallel.For(0,
1000,
options,
(i, state) =>
{
ExecuteSql();
});
}

private void ExecuteSql()
{
SqlDataAdapter adapter = new SqlDataAdapter(sql, new SqlConnection(connectionString));

DataSet orders = new DataSet();
adapter.Fill(orders, "Order");

Console.WriteLine("Thread {0} returned {1} rows", Thread.CurrentThread.ManagedThreadId, orders.Tables[0].Rows.Count);
}

TCPView 结果如下所示,这是我希望在连接池解决方案中看到的结果,即TCP 连接被重用

DatabaseTcpPortTester.vshost.exe    5036    TCP localhost   61316   dev-database01  ms-sql-s    ESTABLISHED 1   88  776 2,684,495       43,800      16      
DatabaseTcpPortTester.vshost.exe 5036 TCP localhost 61317 dev-database01 ms-sql-s ESTABLISHED 1 88 507 1,998,709 6,326 1
DatabaseTcpPortTester.vshost.exe 5036 TCP localhost 61318 dev-database01 ms-sql-s ESTABLISHED 2 176 862 3,081,722 49,640 19
DatabaseTcpPortTester.vshost.exe 5036 TCP localhost 61319 dev-database01 ms-sql-s ESTABLISHED 2 176 952 3,128,657 14,600 9
DatabaseTcpPortTester.vshost.exe 5036 TCP localhost 61320 dev-database01 ms-sql-s ESTABLISHED 2 176 1,149 3,569,440 25,747 8
DatabaseTcpPortTester.vshost.exe 5036 TCP localhost 61321 dev-database01 ms-sql-s ESTABLISHED 2 176 1,166 3,788,974
DatabaseTcpPortTester.vshost.exe 5036 TCP localhost 61322 dev-database01 ms-sql-s ESTABLISHED 2 176 884 3,197,392 8,713 2
DatabaseTcpPortTester.vshost.exe 5036 TCP localhost 61323 dev-database01 ms-sql-s ESTABLISHED 2 176 535 1,816,150
DatabaseTcpPortTester.vshost.exe 5036 TCP localhost 61324 dev-database01 ms-sql-s ESTABLISHED 2 176 631 2,197,973
DatabaseTcpPortTester.vshost.exe 5036 TCP localhost 61327 dev-database01 ms-sql-s ESTABLISHED 2 176 1,037 3,344,226 18,980 5
DatabaseTcpPortTester.vshost.exe 5036 TCP localhost 61328 dev-database01 ms-sql-s ESTABLISHED 3 264 1,271 4,057,097 30,660 13
DatabaseTcpPortTester.vshost.exe 5036 TCP localhost 61331 dev-database01 ms-sql-s ESTABLISHED 2 176 780 2,639,988 8,760 2
DatabaseTcpPortTester.vshost.exe 5036 TCP localhost 61333 dev-database01 ms-sql-s ESTABLISHED 2 176 1,041 3,352,777 31,248 12
DatabaseTcpPortTester.vshost.exe 5036 TCP localhost 61334 dev-database01 ms-sql-s ESTABLISHED 6 995 729 2,387,668
DatabaseTcpPortTester.vshost.exe 5036 TCP localhost 61335 dev-database01 ms-sql-s ESTABLISHED 6 995 601 1,917,537 23,937 6
DatabaseTcpPortTester.vshost.exe 5036 TCP localhost 61336 dev-database01 ms-sql-s ESTABLISHED
DatabaseTcpPortTester.vshost.exe 5036 TCP localhost 61339 dev-database01 ms-sql-s ESTABLISHED
DatabaseTcpPortTester.vshost.exe 5036 TCP localhost 61340 dev-database01 ms-sql-s ESTABLISHED
DatabaseTcpPortTester.vshost.exe 5036 TCP localhost 61342 dev-database01 ms-sql-s ESTABLISHED
DatabaseTcpPortTester.vshost.exe 5036 TCP localhost 61343 dev-database01 ms-sql-s ESTABLISHED
DatabaseTcpPortTester.vshost.exe 5036 TCP localhost 61344 dev-database01 ms-sql-s ESTABLISHED
DatabaseTcpPortTester.vshost.exe 5036 TCP localhost 61345 dev-database01 ms-sql-s ESTABLISHED
DatabaseTcpPortTester.vshost.exe 5036 TCP localhost 61346 dev-database01 ms-sql-s ESTABLISHED
DatabaseTcpPortTester.vshost.exe 5036 TCP localhost 61356 dev-database01 ms-sql-s ESTABLISHED
DatabaseTcpPortTester.vshost.exe 5036 TCP localhost 61357 dev-database01 ms-sql-s ESTABLISHED
DatabaseTcpPortTester.vshost.exe 5036 TCP localhost 61358 dev-database01 ms-sql-s ESTABLISHED
DatabaseTcpPortTester.vshost.exe 5036 TCP localhost 61359 dev-database01 ms-sql-s ESTABLISHED
DatabaseTcpPortTester.vshost.exe 5036 TCP localhost 61362 dev-database01 ms-sql-s ESTABLISHED
DatabaseTcpPortTester.vshost.exe 5036 TCP localhost 61363 dev-database01 ms-sql-s ESTABLISHED
DatabaseTcpPortTester.vshost.exe 5036 TCP localhost 61364 dev-database01 ms-sql-s ESTABLISHED
DatabaseTcpPortTester.vshost.exe 5036 TCP localhost 61365 dev-database01 ms-sql-s ESTABLISHED
DatabaseTcpPortTester.vshost.exe 5036 TCP localhost 61369 dev-database01 ms-sql-s ESTABLISHED
[System Process] 0 TCP localhost 61395 dev-database01 epmap TIME_WAIT

最佳答案

在 netstat 输出中,它们都处于 TIME_WAIT 状态,指示实际关闭之前 TCP 套接字的状态。这并不意味着数据库连接处于 Activity 状态,只是 TCP 处于套接字关闭过程中。

其中有多少处于ESTABLISHED 状态?这将告诉您在那个时间点打开的数据库连接的确切数量。

您可以引用以下链接了解不同的 TCP 套接字状态。 https://en.wikipedia.org/wiki/Transmission_Control_Protocol

关于Java 连接池不限制打开到数据库服务器的 TCP 连接数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34986075/

35 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com