如何为数据库连接池找到合理的大小以及如何验证它?

时间:2013-07-22 06:05:59

标签: java performance hibernate java-ee connection-pooling

我想知道我的connection.pool_size是多少合理的数字?它与哪些方面有关?一旦为其定义了大小,还需要知道如何测试应用程序。

我的应用程序将由AT LEAST 100用户同时使用,它的数据库中有超过20个表。我的数据库是MySQL,至少有12个系统同时使用我的应用程序。如果您需要了解更多信息,请与我们联系。

我还发现以下内容有助于定义连接池大小,但仍然不确定合理的数字是什么。

    Hibernate's own connection pooling algorithm is, however, quite rudimentary.
    It is intended to help you get started and is not intended for use in a production 
    system, or even for performance testing. You should use a third party pool for 
    best performance and stability. Just replace the hibernate.connection.pool_size 
    property with connection pool specific settings. This will turn off Hibernate's 
    internal pool. For example, you might like to use c3p0.

    connection.pool_size indicates the maximum number of pooled connections. So it is 
    better to keep it at a logical count. It depends on your application and DB how 
    much it can handle. 10 is a reasonable count that will typically used as it is 
    sufficient for most cases.

我的hibernateUtil如下

    import org.hibernate.HibernateException;
    import org.hibernate.Session;
    import org.hibernate.SessionFactory;
    import org.hibernate.cfg.Configuration;
    import org.hibernate.service.ServiceRegistry;
    import org.hibernate.service.ServiceRegistryBuilder;

    public class HibernateUtil {

       private static ServiceRegistry serviceRegistry;
       private static final ThreadLocal<Session> threadLocal = new ThreadLocal();
       private static SessionFactory sessionFactory;
        private static SessionFactory configureSessionFactory() {
            try {
                Configuration configuration = new Configuration();
                configuration.configure();
                serviceRegistry = new
ServiceRegistryBuilder().applySettings(configuration.getProperties()).buildServiceRegistry( );
                sessionFactory = configuration.buildSessionFactory(serviceRegistry);
                return sessionFactory;
            } catch (HibernateException e) {
                System.out.append("** Exception in SessionFactory **");
                e.printStackTrace();
            }
           return sessionFactory;
      }

      static {
        try {
          sessionFactory = configureSessionFactory();
        } catch (Exception e) {
          System.err.println("%%%% Error Creating SessionFactory %%%%");
          e.printStackTrace();
        }
      }

      private HibernateUtil() {
      }

      public static SessionFactory getSessionFactory() {
        return sessionFactory;
      }

      public static Session getSession() throws HibernateException {
        Session session = threadLocal.get();

        if (session == null || !session.isOpen()) {
          if (sessionFactory == null) {
            rebuildSessionFactory();
          }
          session = (sessionFactory != null) ? sessionFactory.openSession() : null;
          threadLocal.set(session);
        }

        return session;
      }

      public static void rebuildSessionFactory() {
        try {
          sessionFactory = configureSessionFactory();
        } catch (Exception e) {
          System.err.println("%%%% Error Creating SessionFactory %%%%");
          e.printStackTrace();
        }
      }

      public static void closeSession() throws HibernateException {
        Session session = (Session) threadLocal.get();
        threadLocal.set(null);

        if (session != null) {
          session.close();
        }
      }
    }

4 个答案:

答案 0 :(得分:8)

您必须使用实际框架测试它将使用多少最小和最大连接池。根据{{​​3}}:

小型连接池:

  

可以更快地访问连接表。   但可能没有足够的连接来满足请求和请求   可能会在队列中花费更多时间。

大型连接池:

  

将有更多连接来完成请求   并且请求将花费更少(或没有)时间在队列中   连接表上的访问速度较慢。

因此您必须使用某个连接池进行测试,进行一些负载测试。还要考虑获取当前负载的性能/资源使用信息,并进行一些基于事务成本的分析。

根据分析结果,如果对连接表的访问速度太慢,则可以减少连接池,或者如果连接不够,则可以添加更多连接池。平衡这些因素以获得最佳时间流逝。

答案 1 :(得分:2)

如果您正在使用某些应用程序服务器(Jboss,Weblogic,Glassfish等),这个人可以向您显示有关池使用情况的一些统计信息。分析这些数据(最大队列时间,使用中的最大连接数等)并运行一些测试以找出最适合您情况的数字。

答案 2 :(得分:0)

您必须使用第三方连接池,例如c3p0。 100个concurrecnt用户需要20到30个连接。你必须使用一些工具(如jmeter)进行性能测试。使用性能工具,您可以发送n个concurrecnt请求。根据该报告,您可以增加或减少连接大小。

答案 3 :(得分:0)

了解所需连接数量的唯一合理方法是进行监控和调整。这是因为连接获取时间,池大小和传入请求吞吐量之间的关系由Little's Law给出,因此池大小取决于请求的数量以及您在获取之前愿意等待多长时间一个连接。

FlexyPool是一个开源框架,允许您监视连接使用情况,甚至可以将池大小增加到超出初始容量。

FlexyPool collects the following metrics

  • 并发连接直方图
  • 并发连接请求直方图
  • 数据源连接获取时间直方图
  • 连接租约时间直方图
  • 最大池大小直方图
  • 总连接获取时间直方图
  • 溢出池大小直方图
  • 重试尝试直方图

它支持几乎所有主要的连接池解决方案:

  • Apache DBCP
  • Apache DBCP2
  • C3P0
  • BoneCP
  • HikariCP
  • Tomcat CP
  • Vibur DBCP
  • Bitronix事务管理器
  • Atomikos TransactionsEssentials
  • Java EE DataSources

它使用Codahale / Dropwizard Metrics,因此您可以将它与Graphana或Graphite集成。

所以,回到你的问题。您可以从较小的池大小(5个连接)开始,并配置5个额外连接的溢出缓冲区。您可以根据应用程序SLA(100毫秒)设置超时间隔。然后,您可以监视连接池使用情况as explained in this article