Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java连接池不限制打开到DB服务器的TCP连接数_Java_Spring_Hibernate_Orm_Connection Pooling - Fatal编程技术网

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

Java连接池不限制打开到DB服务器的TCP连接数,java,spring,hibernate,orm,connection-pooling,Java,Spring,Hibernate,Orm,Connection Pooling,我正在使用Hibernate属性定义连接池大小,随着LocalSessionFactoryBean和DriverManagerDataSource创建org.hibernate.SessionFactory,我观察到有1000个TCP连接被打开到DB服务器,而不是连接池大小的上限100 设置连接休眠池的代码如下所示。请注意最大大小为100,但我观察到从工作站到DB服务器的连接数为1000个-我在Windows计算机上使用TCPView连接到由Vagrant(VirtualBox)管理的Cento

我正在使用Hibernate属性定义连接池大小,随着
LocalSessionFactoryBean
DriverManagerDataSource
创建
org.hibernate.SessionFactory
,我观察到有1000个TCP连接被打开到DB服务器,而不是连接池大小的上限100

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

我希望看到这些连接在100处达到最大值,并在以后执行循环时重新使用,但我观察到1000多个连接在关闭前等待了大约一分钟。以下是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注册为原型Spring作用域,而Singleton
SessionFactory
被注入DAO,如下所示:

@Bean(name="jobDao")
@Scope(SpringBeanScope.Prototype)
public JobDao jobDao(SessionFactory jobSessionFactory) { //...}
在DAO中,我调用
sessionFactory.getCurrentSession()
来访问DB会话。以下是通用DAO库的摘录,演示了这一点:

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

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

    currentSession().save(entity);
}
有人知道为什么连接池限制为100时会打开这么多TCP连接吗

更新

由于此问题发生在Windows dev计算机上,因此我创建了一个小型的.NET控制台应用程序,该应用程序使用并行for循环执行一个简单的SQL select语句,最大线程数为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连接被重用


在netstat输出中,它们都处于
TIME\u WAIT
状态,指示TCP套接字在实际关闭之前的状态。这并不意味着数据库连接处于活动状态,只是TCP正在关闭套接字

他们中有多少人处于已建立状态?这将告诉您在该时间点打开的DB连接的确切数量


您可以参考以下链接了解不同的TCP套接字状态

Hibernate配置正确,您应该使用C3P0。如果您为每个请求创建
SessionFactory
,则可以看到比最大池大小更多的连接


从您的配置中,我看到DAO是作为原型创建的,这是不寻常的,因为它们应该是单例的。确保
LocalSessionFactoryBean
也不使用原型作用域。

问题是,当使用
DriverManager数据源时,c3p0从未初始化,并且让hibernate通过在
LocalSessionFactoryBean
上设置c3p0属性来管理池

因此,我切换到一个
ComboPooledDataSource
,并使用此处可用的setter方法设置c3p0属性,而不是在
LocalSessionFactoryBean
上设置,因此您实际上可以得到以下结果:

@Bean(name="dataSource")
public DataSource dataSource() throws PropertyVetoException {

    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);

    //note the "hibernate.c3p0...." properties are no longer in use

    ComboPooledDataSource dataSource = new ComboPooledDataSource();

    dataSource.setDriverClass(jobDatabaseProperties.getJobDatabaseDriverClassName());
    dataSource.setJdbcUrl(jobDatabaseProperties.getJobDatabaseUrl());
    dataSource.setUser(jobDatabaseProperties.getJobDatabaseUsername());
    dataSource.setPassword(jobDatabaseProperties.getJobDatabasePassword());

    dataSource.setAcquireIncrement(1);
    dataSource.setMinPoolSize(5);
    dataSource.setMaxPoolSize(100);
    dataSource.setMaxIdleTime(20);

    return new dataSource;
}
我现在可以看到c3p0在日志中被初始化,连接的数量按预期由池控制


关于“让Spring管理池”

一节的帽子提示我认为是这样的,但问题是要跨更多线程处理的项目数量更多,我正在耗尽机器上的端口,因为释放这些端口需要一分钟(windows上为72秒)。我是否错过了提前释放这些端口的hibernate设置,或者这是我需要更改的操作系统配置?几乎所有这些都是。正如我们预期的那样,在多达20个线程的线程池中,一次只有3-4个活动(已建立)线程,但时间为100秒,有时为1000秒。\u等待一分钟以上,我一定是做错了什么,因为每次调用session.save(或者session.getCurrentSession,不确定)时,似乎都会打开一个连接这在我看来是错误的,因为一个操作系统可以支持/打开2^16个端口(理论上),除非你看到上面的一些东西,比如25000个大数字,在TIME\u WAIT状态下的条目,我们不应该担心那些TIME\u WAIT状态。操作系统将接管它。另外,由于您只看到3-4个活动连接,您可能需要检查的一些指标是web/app服务器的线程池配置,或者GC是否导致了处理延迟,或者java进程是否渴望内存或资源。您可能还想进行一些线程转储,看看您的代码是否在同步上等待了太多时间。我创建了一个.NET测试应用程序(因为我在Windows上),它对SQL Server DB运行一个简单的SELECT语句。我在并行for循环中运行了1000次迭代,最多32个线程,结果与Java完全不同。请参阅我对以下问题的最新更新:工厂是单例的,DAO是原型,因此同一个会话不会在线程之间共享(这不是web应用程序)。我也尝试过singleton DAO,但也出现了会话关闭错误,并且在TIMRE_等待状态下观察到了相同的连接问题,因此基于此,我确信原型是正确的。
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
@Bean(name="dataSource")
public DataSource dataSource() throws PropertyVetoException {

    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);

    //note the "hibernate.c3p0...." properties are no longer in use

    ComboPooledDataSource dataSource = new ComboPooledDataSource();

    dataSource.setDriverClass(jobDatabaseProperties.getJobDatabaseDriverClassName());
    dataSource.setJdbcUrl(jobDatabaseProperties.getJobDatabaseUrl());
    dataSource.setUser(jobDatabaseProperties.getJobDatabaseUsername());
    dataSource.setPassword(jobDatabaseProperties.getJobDatabasePassword());

    dataSource.setAcquireIncrement(1);
    dataSource.setMinPoolSize(5);
    dataSource.setMaxPoolSize(100);
    dataSource.setMaxIdleTime(20);

    return new dataSource;
}