通过 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 应用程序。这几乎与第一个选项一样有效,但如果实例不健康,它们仍然可以重新启动。在这种情况下,请确保您有 健康检查 设置,以便在发生某些事情时修复您的实例。这将使他们尽可能地活着和工作。
我将 Hibernate v5 与 GAE Flexible 环境和云结合使用 SQL。
一切正常,但是当一个实例被唤醒或者在一些冷时间之后(没有服务请求),它需要很长时间才能连接到数据库(最多8s)而查询的执行只需要小姐。它还一次又一次地创建 serviceRegistry。
任何人都可以建议什么是连接云的最佳方法SQL避免在获得连接时出现更高的延迟。
PS: 我正在使用 cp30 作为连接池。
来自应用引擎的日志:
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 应用程序。这几乎与第一个选项一样有效,但如果实例不健康,它们仍然可以重新启动。在这种情况下,请确保您有 健康检查 设置,以便在发生某些事情时修复您的实例。这将使他们尽可能地活着和工作。