Рубрики
Без рубрики

Настройка производительности пружинной загрузки

Узнайте, как ускорить уровень доступа к данным в приложении Spring Boot с помощью утилиты настройки производительности оптимизатора гиперсистенции.

Автор оригинала: Vlad Mihalcea.

Вступление

Хотя разработка приложения Spring Boot довольно проста, настройка производительности приложения Spring Boot является более сложной задачей, поскольку для этого требуется не только понять, как работает платформа Spring за кулисами, но и знать, как лучше всего использовать базовую платформу доступа к данным, например, Hibernate.

В предыдущей статье я показал вам , как легко оптимизировать производительность демонстрационного приложения Petclinic. Однако по умолчанию приложение Petclinic Spring Boot использует базу данных HSQLDB в памяти, для которой вы обычно не хотите, чтобы ваше приложение было оптимизировано.

В этой статье мы собираемся переключить базовую базу данных с HSQLDB в памяти на MySQL и запустить оптимизатор гиперсистенции для создания отчета о настройке производительности для JPA и гибернации уровня доступа к данным в контексте базы данных MySQL.

Настройка производительности приложения #SpringBoot может быть сложной задачей. @vlad_mihalcea показывает вам #как создать отчет о настройке производительности для #JPA и Гибернировать уровень доступа к данным в контексте #MySQL базы данных.

Весенняя Петклиника

Spring Petclinic – это демонстрационное приложение, созданное с использованием Spring Boot, которое демонстрирует возможности платформы.

По умолчанию Spring Boot использует HSQLDB, но, хотя эта база данных в памяти широко используется для тестирования, в производственной среде вы, скорее всего, будете использовать базу данных, такую как MySQL или PostgreSQL.

К счастью, Spring Boot предлагает конфигурацию MySQL и профиль Spring, которые мы можем использовать в качестве отправной точки для нашего анализа.

Переключение тестов на использование профиля MySQL

Прежде всего, нам нужно использовать аннотацию @ActiveProfiles для активации mysql Профиль пружины.

@RunWith(SpringRunner.class)
@SpringBootTest
@ActiveProfiles("mysql")
public class PetclinicIntegrationTests {

    @Autowired
    private VetRepository vets;

    @Test
    public void testFindAll() throws Exception {
        vets.findAll();
        vets.findAll(); // served from cache
    }
}

После активации mysql Профиль Spring, загрузка Spring будет использовать файл конфигурации application-mysql.properties для переопределения параметров из файла настроек по умолчанию application.properties .

В нашем случае единственным изменением, которое требовалось внести в файл конфигурации application-mysql.properties , было изменение учетных данных подключения к базе данных:

database=mysql

spring.datasource.url=jdbc:mysql://localhost/petclinic
spring.datasource.username=mysql
spring.datasource.password=admin

Запуск оптимизатора сохраняемости Hy

Как вы можете видеть в классе Интеграционные тесты клиники домашних животных , запустить оптимизатор гиперситуации очень просто, так как вам просто нужно пройти EntityManagerFactory экземпляр в гиперсистенци-оптимизатор конструктор объектов и вызов метода init .

Hypersistence Optimizer : CRITICAL - TableGeneratorEvent - 
The [id] identifier attribute in the [org.springframework.samples.petclinic.owner.Pet] entity uses the TABLE strategy, which does not scale very well. Consider using the IDENTITY identifier strategy instead, even if it does not allow JDBC batch inserts.
For more info about this event, check out this User Guide link - https://vladmihalcea.com/hypersistence-optimizer/docs/user-guide/#TableGeneratorEvent

Hypersistence Optimizer : CRITICAL - TableGeneratorEvent - 
The [id] identifier attribute in the [org.springframework.samples.petclinic.owner.Owner] entity uses the TABLE strategy, which does not scale very well. Consider using the IDENTITY identifier strategy instead, even if it does not allow JDBC batch inserts.
For more info about this event, check out this User Guide link - https://vladmihalcea.com/hypersistence-optimizer/docs/user-guide/#TableGeneratorEvent

Hypersistence Optimizer : CRITICAL - TableGeneratorEvent - 
The [id] identifier attribute in the [org.springframework.samples.petclinic.visit.Visit] entity uses the TABLE strategy, which does not scale very well. Consider using the IDENTITY identifier strategy instead, even if it does not allow JDBC batch inserts.
For more info about this event, check out this User Guide link - https://vladmihalcea.com/hypersistence-optimizer/docs/user-guide/#TableGeneratorEvent

Hypersistence Optimizer : CRITICAL - TableGeneratorEvent - 
The [id] identifier attribute in the [org.springframework.samples.petclinic.owner.PetType] entity uses the TABLE strategy, which does not scale very well. Consider using the IDENTITY identifier strategy instead, even if it does not allow JDBC batch inserts.
For more info about this event, check out this User Guide link - https://vladmihalcea.com/hypersistence-optimizer/docs/user-guide/#TableGeneratorEvent

Hypersistence Optimizer : CRITICAL - TableGeneratorEvent - 
The [id] identifier attribute in the [org.springframework.samples.petclinic.vet.Specialty] entity uses the TABLE strategy, which does not scale very well. Consider using the IDENTITY identifier strategy instead, even if it does not allow JDBC batch inserts.
For more info about this event, check out this User Guide link - https://vladmihalcea.com/hypersistence-optimizer/docs/user-guide/#TableGeneratorEvent

Hypersistence Optimizer : CRITICAL - TableGeneratorEvent - 
The [id] identifier attribute in the [org.springframework.samples.petclinic.vet.Vet] entity uses the TABLE strategy, which does not scale very well. Consider using the IDENTITY identifier strategy instead, even if it does not allow JDBC batch inserts.
For more info about this event, check out this User Guide link - https://vladmihalcea.com/hypersistence-optimizer/docs/user-guide/#TableGeneratorEvent

Hypersistence Optimizer : MAJOR - DialectVersionEvent - 
Your application is using the [org.hibernate.dialect.MySQL5Dialect] Hibernate-specific Dialect. Consider using the [org.hibernate.dialect.MySQL57Dialect] instead as it's closer to your current database server version [MySQL 8.0].
For more info about this event, check out this User Guide link - https://vladmihalcea.com/hypersistence-optimizer/docs/user-guide/#DialectVersionEvent

Событие Генератора таблиц

Событие Генератор таблиц запускается, потому что в предыдущей статье мы переключили стратегию идентификатора сущности с ИДЕНТИЧНОСТИ на ПОСЛЕДОВАТЕЛЬНОСТЬ .

Использование стратегии ПОСЛЕДОВАТЕЛЬНОСТИ идентификаторов является лучшим вариантом, если и только если базовая база данных поддерживает объекты последовательности. Однако MySQL 8 не поддерживает последовательности баз данных, и по этой причине Hibernate переключается на использование генератора ТАБЛИЦ , и, как объясняется в его статье , генератор ТАБЛИЦ является ужасным выбором , когда дело доходит до производительности приложений.

Переход на использование идентификатора для MySQL

Таким образом, в нашем случае нам лучше использовать генератор IDENTITY для MySQL. Однако мы не хотим изменять сопоставления сущностей на IDENTITY , поскольку нам может потребоваться развернуть приложение Petclinic в других системах баз данных, таких как Oracle, SQL Server или PostgreSQL, которые поддерживают последовательности баз данных. Итак, мы хотим, чтобы сопоставление по умолчанию использовало стратегию SEQUENCE , но изменило ее только на IDENTITY для MySQL.

Даже если генератор IDENTITY не позволяет Hibernate паковать инструкции INSERT на уровне JDBC, все равно лучше использовать эту стратегию, а не генератор TABLE . Для получения более подробной информации о пакетных обновлениях JDBC ознакомьтесь с этой статьей .

И решение на самом деле очень простое. На самом деле, я уже объяснял это в этой статье .

Путем предоставления специфичного для MySQL orm.xml Файл конфигурации JPA, который переопределяет стратегию идентификатора сущности базового класса, мы можем переключиться на использование IDENTITY при использовании MySQL.

Итак, мы собираемся создать orm.xml файл, который будет развернут профилем mysql в папке META-INF в файле приложения jar .

В orm.xml файл конфигурации выглядит следующим образом:





    
        
            
                
            
        
    


Вот и все!

Теперь при повторном запуске интеграционных тестов Pet clinic тестового случая оптимизатор Гиперсистенции создаст следующий отчет:

Hypersistence Optimizer : MINOR - IdentityGeneratorEvent - 
The [id] identifier attribute in the [org.springframework.samples.petclinic.owner.Pet] entity uses the [IdentityGenerator] strategy, 
which prevents Hibernate from enabling JDBC batch inserts. 
Since the database does not support the SEQUENCE identifier strategy, 
you need to use plain JDBC or some other data access framework to batch insert statements. 
For more info about this event, check out this User Guide link - https://vladmihalcea.com/hypersistence-optimizer/docs/user-guide/#IdentityGeneratorEvent

Hypersistence Optimizer : MINOR - IdentityGeneratorEvent - 
The [id] identifier attribute in the [org.springframework.samples.petclinic.owner.Owner] entity uses the [IdentityGenerator] strategy, 
which prevents Hibernate from enabling JDBC batch inserts. 
Since the database does not support the SEQUENCE identifier strategy, you need to use plain JDBC or some other data access framework to batch insert statements. 
For more info about this event, check out this User Guide link - https://vladmihalcea.com/hypersistence-optimizer/docs/user-guide/#IdentityGeneratorEvent

Hypersistence Optimizer : MINOR - IdentityGeneratorEvent - 
The [id] identifier attribute in the [org.springframework.samples.petclinic.visit.Visit] entity uses the [IdentityGenerator] strategy, 
which prevents Hibernate from enabling JDBC batch inserts. 
Since the database does not support the SEQUENCE identifier strategy, you need to use plain JDBC or some other data access framework to batch insert statements. 
For more info about this event, check out this User Guide link - https://vladmihalcea.com/hypersistence-optimizer/docs/user-guide/#IdentityGeneratorEvent

Hypersistence Optimizer : MINOR - IdentityGeneratorEvent - 
The [id] identifier attribute in the [org.springframework.samples.petclinic.owner.PetType] entity uses the [IdentityGenerator] strategy, 
which prevents Hibernate from enabling JDBC batch inserts. 
Since the database does not support the SEQUENCE identifier strategy, you need to use plain JDBC or some other data access framework to batch insert statements. 
For more info about this event, check out this User Guide link - https://vladmihalcea.com/hypersistence-optimizer/docs/user-guide/#IdentityGeneratorEvent

Hypersistence Optimizer : MINOR - IdentityGeneratorEvent - 
The [id] identifier attribute in the [org.springframework.samples.petclinic.vet.Specialty] entity uses the [IdentityGenerator] strategy, 
which prevents Hibernate from enabling JDBC batch inserts. 
Since the database does not support the SEQUENCE identifier strategy, you need to use plain JDBC or some other data access framework to batch insert statements. 
For more info about this event, check out this User Guide link - https://vladmihalcea.com/hypersistence-optimizer/docs/user-guide/#IdentityGeneratorEvent

Hypersistence Optimizer : MINOR - IdentityGeneratorEvent - 
The [id] identifier attribute in the [org.springframework.samples.petclinic.vet.Vet] entity uses the [IdentityGenerator] strategy, 
which prevents Hibernate from enabling JDBC batch inserts. 
Since the database does not support the SEQUENCE identifier strategy, you need to use plain JDBC or some other data access framework to batch insert statements. 
For more info about this event, check out this User Guide link - https://vladmihalcea.com/hypersistence-optimizer/docs/user-guide/#IdentityGeneratorEvent

Hypersistence Optimizer : MAJOR - DialectVersionEvent - 
Your application is using the [org.hibernate.dialect.MySQL5Dialect] Hibernate-specific Dialect. Consider using the [org.hibernate.dialect.MySQL57Dialect] instead as it's closer to your current database server version [MySQL 8.0].
For more info about this event, check out this User Guide link - https://vladmihalcea.com/hypersistence-optimizer/docs/user-guide/#DialectVersionEvent

Обратите внимание, что событие Генератор таблиц было заменено Генератором идентификаторов . Генератор идентификаторов генерируется, потому что стратегия IDENTITY не позволяет Hibernate выполнять пакетные инструкции INSERT при вызове persist поскольку ему необходимо знать идентификатор сущности при связывании сохраняющейся сущности с кэшем первого уровня.

Но поскольку у нас на самом деле нет опции для Генератора идентификаторов при использовании MySQL, мы можем просто проигнорировать это событие в нашем случае.

Фильтрация событий оптимизатора Гиперстабильности

Оптимизатор гиперсиленса очень гибкий. Вы можете настроить, как обрабатываются события , хотите ли вы, чтобы они регистрировались или собирались в Список , а также можете выбрать фильтрацию событий.

Чтобы отфильтровать событие Генератор идентификационных данных , вам необходимо настроить Гиперстистенционный оптимизатор компонент следующим образом:

@Configuration
public class HypersistenceConfiguration {
    @Bean
    public HypersistenceOptimizer hypersistenceOptimizer(
            EntityManagerFactory entityManagerFactory) {
        return new HypersistenceOptimizer(
            new JpaConfig(entityManagerFactory)
                .setEventFilter(
                    event -> !(event instanceof IdentityGeneratorEvent)
                )
        );
    }
}

Теперь при повторном запуске интеграционных тестов Pet clinic тестового случая оптимизатор гиперсуществования предотвратит включение в отчет события identitygenerator/|:

Hypersistence Optimizer : MAJOR - DialectVersionEvent - 
Your application is using the [org.hibernate.dialect.MySQL5Dialect] Hibernate-specific Dialect. Consider using the [org.hibernate.dialect.MySQL57Dialect] instead as it's closer to your current database server version [MySQL 8.0].
For more info about this event, check out this User Guide link - https://vladmihalcea.com/hypersistence-optimizer/docs/user-guide/#DialectVersionEvent

Событие Диалектной версии

Событие Версия диалекта генерируется, потому что по умолчанию настроен диалект гибернации MySQL57Dialect в то время как приложение Petclinic работает против MySQL 8.

Итак, нам просто нужно включить Диалект MySQL 8 в файл конфигурации Spring Boot application-mysql.properties :

database=mysql

spring.datasource.url=jdbc:mysql://localhost/petclinic
spring.datasource.username=mysql
spring.datasource.password=admin

spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQL8Dialect

И теперь оптимизатор персистентности Hy не сообщает о каких-либо проблемах. Круто, правда?

Вывод

Оптимизатор гиперсистенции-это очень мощный инструмент, который может помочь вам обнаружить проблемы с производительностью JPA и гибернации задолго до того, как они возникнут в производственной системе.

И одним из его самых больших преимуществ является то, что он может выполнять все эти проверки при каждой фиксации, так что вы больше не будете упускать из виду повышение производительности JPA или гибернации из-за очень плотного графика разработки.

Все оптимизации, представленные в этой статье, можно найти в этом репозитории GitHub .