通过 GAE Flex 中的连接池连接 Cloud SQL 的最佳方式

Best way to connect Cloud SQL via connection pooling in GAE Flex

我将 Hibernate v5 与 GAE Flexible 环境和云结合使用 SQL。

一切正常,但是当一个实例被唤醒或者在一些冷时间之后(没有服务请求),它需要很长时间才能连接到数据库(最多8s)而查询的执行只需要小姐。它还一次又一次地创建 serviceRegistry

任何人都可以建议什么是连接云的最佳方法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;

我不太确定你所说的 "an instance is waken up" 是什么意思,因为一个实例是活的还是死的。空闲时它做什么取决于你的scaling settings in the app.yaml,要么死要么保持空闲。

我认为 sessionFactory 的创建是延迟的原因。这是一个代价高昂的过程,因为会话工厂封装了会话对象、连接、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;
    }
}

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

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

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

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

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