【问题标题】:Best way to connect Cloud SQL via connection pooling in GAE Flex通过 GAE Flex 中的连接池连接 Cloud SQL 的最佳方式
【发布时间】:2018-08-05 13:01:42
【问题描述】:

我将 Hibernate v5 与 GAE 灵活环境和 Cloud SQL 结合使用。

一切正常,但是当一个实例被唤醒或经过一段时间的冷时间(没有请求服务)后,连接数据库需要很长时间(最多 8 秒),而查询的执行只需要毫秒。它还一次又一次地创建 serviceRegistry

谁能建议什么是连接 Cloud SQL 的最佳方法,以避免在获得连接时产生更高的延迟。

PS:我正在使用 cp30 进行连接池。

来自应用引擎的日志:

HibernateUtil 配置:

        props.put("hibernate.hbm2ddl.auto", "validate");
        props.put("hibernate.dialect", "org.hibernate.dialect.MySQL5InnoDBDialect");
        props.put("hibernate.generate_statistics", "true");
        props.put("hibernate.cache.use_query_cache", "true");
        props.put("hibernate.transaction.coordinator_class", "org.hibernate.transaction.JDBCTransactionFactory");
        props.put("hibernate.cache.region.factory_class", "org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory");
        props.put("hibernate.cache.use_second_level_cache", "true");

        props.put("connection.provider_class", "org.hibernate.connection.C3P0ConnectionProvider");
        props.put("hibernate.c3p0.min_size", "40");
        props.put("hibernate.c3p0.max_size", "250");
        props.put("hibernate.c3p0.acquire_increment", "1");
        props.put("hibernate.c3p0.testConnectionOnCheckin", "true");
        props.put("hibernate.c3p0.idle_test_period", "300");
        props.put("hibernate.c3p0.maxIdleTimeExcessConnections", "240");
        props.put("hibernate.c3p0.preferredTestQuery", "SELECT 1");
         ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build();
        System.out.println("Hibernate Java Config serviceRegistry created");

        SessionFactory sessionFactory = configuration.buildSessionFactory(serviceRegistry);

        return sessionFactory;

【问题讨论】:

    标签: java sql google-app-engine google-cloud-platform google-cloud-sql


    【解决方案1】:

    除非您使用manual scaling,否则您的实例通常会被终止并重新启动。实例在启动时必须重新加载所有库和配置,因此预期的行为需要更长的时间。

    您的用例有两个简单的选项:

    1) 使用Compute Engine instance,它允许您加载代码、库和配置,它是一个专用 VM,将继续为您的请求提供服务,并且不会“缩减”(终止)。这绝对是最安全的方法。

    2) 使用 manual scaling 扩展您的 App Engine Flex 应用程序。这几乎与第一个选项一样有效,但如果实例运行状况不佳,仍然可以重新启动它们。在这种情况下,请确保您已设置 health check 以在发生某些情况时修复您的实例。这将使他们尽可能地保持活力和工作。

    【讨论】:

    • 感谢@ying-li 的回答。有什么方法可以在实例启动后立即连接到数据库。
    • 你说的是自动缩放还是手动缩放?使用自动扩展,实例在请求进来时启动,这就是为什么总是有加载时间的原因。如果您在谈论手动扩展,那么实例始终准备就绪,当请求进来时,它应该会自动处理。
    【解决方案2】:

    我不确定您所说的“实例被唤醒”是什么意思,因为实例要么活着要么死了。空闲时的作用取决于你的scaling settings in the app.yaml,要么死,要么保持空闲。

    我认为 sessionFactory 的创建是延迟的原因。这是一个代价高昂的过程,因为 Session 工厂封装了会话对象、连接、Hibernate 属性缓存和映射。

    我很想知道如果你重用 sessionFactory 会发生什么(根据示例无耻地从 here 窃取):

    package net.codejava.hibernate;
    
    import org.hibernate.SessionFactory;
    import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
    import org.hibernate.cfg.Configuration;
    import org.hibernate.service.ServiceRegistry;
    
    public class HibernateUtil {
        private static SessionFactory sessionFactory;
    
        public static SessionFactory getSessionFactory() {
            if (sessionFactory == null) {
                // loads configuration and mappings
                Configuration configuration = new Configuration().configure();
                ServiceRegistry serviceRegistry
                    = new StandardServiceRegistryBuilder()
                        .applySettings(configuration.getProperties()).build();
    
                // builds a session factory from the service registry
                sessionFactory = configuration.buildSessionFactory(serviceRegistry);           
            }
    
            return sessionFactory;
        }
    }
    

    由于您没有提供完整的代码,您必须根据自己的情况调整此示例。

    【讨论】:

    • “一个实例被唤醒”是指当谷歌创建一个新实例来服务流量时,发布最少数量的实例。
    猜你喜欢
    • 2010-11-15
    • 2018-05-25
    • 1970-01-01
    • 2010-10-09
    • 1970-01-01
    • 2011-08-01
    • 1970-01-01
    • 2018-06-26
    • 1970-01-01
    相关资源
    最近更新 更多