Performance hibernate会话初始化在生产环境中非常缓慢,有许多实体定义
我有一个Spring Boot应用程序,其中有296个持久化对象,由@Entity使用Hibernate框架对persistence实现进行注释。在核心i7-6700(4x 3.4Ghz-4Ghz Turbo,SSD)上使用eclipse进行开发时,SessionFactory几乎在6秒钟内初始化 我的生产服务器是Xeon E5-2620v2(6x2,1GHz-2.6Ghz,硬盘(+SSD缓存))上的虚拟化windows服务器。我无法控制虚拟化所分配的资源 当我在这台服务器上运行我的应用程序时,实例化SessionFactory大约需要25秒 应用程序完全初始化时没有速度问题:所有Web服务/数据库查询的执行速度正常 我天真地认为,hibernate在实例化SessionFactory时会创建基本CRUD操作的SQL查询。 我尝试在所有@Entity类上添加@DynamicInsert和@DynamicUpdate,但没有给我带来更好的启动时间,SessionFactory实例化时间也是一样的 我使用以下spring/hibernate/others相关库版本:(来自我的pom.xml) 这就是我定义hibernate SessionFactory的方式(我知道我可以使用标准的JPA会话工厂,但这个应用程序就是这样制作的,我不想改变它,而且我简化了类内容以提高可读性): 这种速度差正常吗? 我忘了hibernate配置中的一些东西了吗?Performance hibernate会话初始化在生产环境中非常缓慢,有许多实体定义,performance,hibernate,spring-boot,session,initialization,Performance,Hibernate,Spring Boot,Session,Initialization,我有一个Spring Boot应用程序,其中有296个持久化对象,由@Entity使用Hibernate框架对persistence实现进行注释。在核心i7-6700(4x 3.4Ghz-4Ghz Turbo,SSD)上使用eclipse进行开发时,SessionFactory几乎在6秒钟内初始化 我的生产服务器是Xeon E5-2620v2(6x2,1GHz-2.6Ghz,硬盘(+SSD缓存))上的虚拟化windows服务器。我无法控制虚拟化所分配的资源 当我在这台服务器上运行我的应用程序时,
欢迎提供任何帮助。您的虚拟服务器有多少资源?@Simon Martinelli我的虚拟服务器有4个vCPU(2.10 Ghz),32 GB的RAM(但我将我的应用程序实例限制为-Xms256m-Xmx512m-性能相同,没有RAM限制)。目前,我对虚拟服务器资源还不太了解。你认为这可能是问题的根源吗,那么我应该调查一下?你在本地运行时也限制XMX吗?不,但我刚刚尝试过,SessionFactory实例化时间是相同的(~6秒),你有一个HDD而不是SDD,对吗?还有病毒扫描器吗?你的虚拟服务器有多少资源?@Simon Martinelli我的虚拟服务器有4个vCPU(2.10 Ghz),32 GB的RAM(但我用-Xms256m-Xmx512m限制我的应用程序实例-没有RAM限制,性能相同)。目前,我对虚拟服务器资源还不太了解。你认为这可能是问题的根源吗,那么我应该调查一下?你在本地运行时也限制XMX吗?不,但我刚刚尝试过,SessionFactory实例化时间是相同的(~6秒),你有一个HDD而不是SDD,对吗?有病毒扫描器吗?
<hibernate.version>5.4.5.Final</hibernate.version>
<spring.version>5.1.9.RELEASE</spring.version>
<springSecurity.version>5.1.6.RELEASE</springSecurity.version>
<springBoot.version>2.1.8.RELEASE</springBoot.version>
<mssql-jdbc.version>7.4.1.jre11</mssql-jdbc.version>
<apache-commons-dbcp2.version>2.5.0</apache-commons-dbcp2.version>
<eh-cache.version>2.10.6</eh-cache.version>
<javaassist.version>3.25.0-GA</javaassist.version>
hibernate.dialect = org.hibernate.dialect.SQLServer2012Dialect
# useless cause I use GenerationType.IDENTITY
# for primary key (id) of all entities
hibernate.jdbc.batch_size = 20
hibernate.cache.use_query_cache = false
hibernate.cache.use_second_level_cache = true
hibernate.cache.provider_class = org.hibernate.cache.EhCacheProvider
hibernate.cache.region.factory_class = org.hibernate.cache.ehcache.SingletonEhCacheRegionFactory
hibernate.connection.driver_class = com.microsoft.sqlserver.jdbc.SQLServerDriver
hibernate.enable_lazy_load_no_trans = true
hibernate.cache.use_reference_entries = true
hibernate.connection.url = jdbc:sqlserver://localhost:1433;databaseName=master;user=usr;password=pwd;
hibernate.connection.username = usr
hibernate.connection.password = pwd
# Multitenancy configuration
hibernate.multiTenancy = SCHEMA
hibernate.multi_tenant_connection_provider = MultiTenantConnectionProvider
hibernate.tenant_identifier_resolver = CurrentTenantIdentifierResolver
@SpringBootApplication()
@EnableAutoConfiguration(
excludeName = {
"org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration"
}
)
@ComponentScan(
basePackages = {
// my packages list
}
)
@Configuration
@PropertySource({ "classpath:application.mssql.properties" })
@EnableCaching
@EnableTransactionManagement
public class ApplicationConfiguration {
@Autowired
private Environment env;
/**
* @return SQL-Server pooled connection using apache dbcp2
*/
@Primary
@Bean
public DataSource dataSource() {
BasicDataSource ds = new BasicDataSource();
ds.setUrl(this.env.get("hibernate.connection.url"));
ds.setUsername(this.env.get("hibernate.connection.username"));
ds.setPassword(this.env.get("hibernate.connection.password"));
ds.setDriverClassName(this.env.get("hibernate.connection.driver_class"));
ds.setMaxIdle(10);
ds.setMaxOpenPreparedStatements(100);
return ds;
}
/**
* @return main sessionFactory (the mostly used sessionFactory in app)
*/
@Primary
@Autowired
@Bean
public LocalSessionFactoryBean sessionFactory(@Qualifier("dataSource") DataSource dataSource,
MultiTenantConnectionProvider multiTenantConnectionProviderImpl,
CurrentTenantIdentifierResolver currentTenantIdentifierResolverImpl) {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setPackagesToScan("my.root.pojo.package");
// get hibernate properties from this.env (application.mssql.properties file)
Properties hibernateProperties = getHibernateProperties();
hibernateProperties.put(AvailableSettings.MULTI_TENANT, "SCHEMA");
hibernateProperties.put(AvailableSettings.MULTI_TENANT_CONNECTION_PROVIDER, multiTenantConnectionProviderImpl);
hibernateProperties.put(AvailableSettings.MULTI_TENANT_IDENTIFIER_RESOLVER, currentTenantIdentifierResolverImpl);
sessionFactory.setHibernateProperties(hibernateProperties);
sessionFactory.setDataSource(dataSource);
return sessionFactory;
// FROM THIS POINT --->
}
/**
* @return transactionManager for main sessionFactory
*/
@Bean
@Autowired
@Primary
public HibernateTransactionManager transactionManager(@Qualifier("sessionFactory") SessionFactory sessionFactory) {
// ----> TO THIS POINT took 6 sec in development, 25 sec in production
HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setNestedTransactionAllowed(true);
txManager.setSessionFactory(sessionFactory);
return txManager;
}
// some other stuff:
// - sessionFactory on another databases,
// - getHibernateProperties() implementation,
// - initServer() method annotated by @Bean(initMethod = "init")
// - etc ...
}