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

Давайте сделаем так, чтобы приложение Spring Boot запускалось быстрее

“Как быстро наступает весна?” это сессия на платформе Spring One 2018. Я посмотрел видео и тр… С тегом java, весенняя загрузка.

“Как быстро наступает весна?”

это сессия на платформе Spring One 2018. Я посмотрел видео и попробовал его сам. Поэтому я представляю здесь то, что я сделал, и результаты.

Я рекомендую вам посмотреть это видео сеанса, если вы еще этого не сделали. Это так интересно.

Это так интересно.

Сегодняшний исходный код

Сегодняшний исходный код

↓ Я использовал OpenJDK 11.

❯ java --version
openjdk 11.0.1 2018-10-16
OpenJDK Runtime Environment 18.9 (build 11.0.1+13)
OpenJDK 64-Bit Server VM 18.9 (build 11.0.1+13, mixed mode)

↓ Вы можете запустить все тесты таким образом. Это займет некоторое время, потому что он выполняет все контрольные показатели.

❯ ./mvnw clean package
❯ (cd benchmarks/; java -jar target/benchmarks.jar)

1. Базовая линия потока

↓ Я создал проект, используя SpringInitializr только с помощью реактивной сети. Затем я написал крошечный контроллер в стиле Web MVC.

@SpringBootApplication
@RestController
public class DemoApplication {

  @GetMapping("/")
  public String home() {
    return "Hello";
  }

  public static void main(String[] args) {
    SpringApplication.run(DemoApplication.class, args);
  }
}

↓ Версия Spring Boot была 2.1.0.ВЫПУСКА.

    
        org.springframework.boot
        spring-boot-starter-parent
        2.1.0.RELEASE
         
    

↓ Для запуска потребовалось 2,938 ± 0,287 с/оп.

Benchmark                                          Mode  Cnt  Score   Error  Units
MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op

Теперь у меня есть базовая линия для проверки времени запуска. Давайте начнем отсюда.

2. ВебМВК

↓ Мне было интересно, как насчет WebMVC, а не WebFlux? Поэтому я попробовал. Может быть, это просто означает сравнение Кота и Нетти?

Benchmark                                          Mode  Cnt  Score   Error  Units
MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
MyBenchmark.case02_Web                               ss   10  3.281 ± 0.342   s/op

Веб-поток немного быстрее, не так ли?

3. весна-контекст-индексы

Затем я попробовал spring-context-индексы, которые, похоже, создают индекс компонентов.

        
            org.springframework
            spring-context-indexer
            true
        

↓ Эм… немного медленнее?

Benchmark                                          Mode  Cnt  Score   Error  Units
MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
MyBenchmark.case03_WithContextIndexer                ss   10  3.063 ± 0.102   s/op

↓Я проверил spring.components и обнаружил, что он содержит только 1 компонент. Я понимаю… Я должен попробовать с большим проектом, чтобы узнать эффект.

#
#Sun Nov 04 18:42:59 JST 2018
com.example.DemoApplication=org.springframework.stereotype.Component

4. Ленивая инициализация

Попробовал Ленивый Ввод.

@Configuration
public class LazyInitBeanFactoryPostProcessor implements BeanFactoryPostProcessor {
  @Override
  public void postProcessBeanFactory(ConfigurableListableBeanFactory beanFactory) throws BeansException {
    for (String beanName : beanFactory.getBeanDefinitionNames()) {
      beanFactory.getBeanDefinition(beanName).setLazyInit(true);
    }
  }
}

↓ Вот результат. Это стало просто немного быстрее.

Benchmark                                          Mode  Cnt  Score   Error  Units
MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
MyBenchmark.case04_WithLazyInit                      ss   10  2.844 ± 0.129   s/op

5. Новерифицировать

Бежал с - новерифицировать :

Benchmark                                          Mode  Cnt  Score   Error  Units
MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
MyBenchmark.case05_WithNoVerifyOption                ss   10  2.582 ± 0.060   s/op

Это стало немного быстрее. Я не знаю, что это значит, поэтому мне нужно проверить это как-нибудь позже.

6. Многоуровневый уровень

Бежал с -XX: Многоуровневый уровень=1 :

Benchmark                                          Mode  Cnt  Score   Error  Units
MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
MyBenchmark.case06_WithTieredStopAtLevel1Option      ss   10  1.980 ± 0.037   s/op

Ух, намного быстрее! Это заняло менее 2 секунд. Но я тоже не знаю этого флага. Так что я проверю это позже.

7. Явно укажите местоположение конфигурации Spring

Запускался с -Dspring.config.location= путь к классу:/application.свойства :

Benchmark                                          Mode  Cnt  Score   Error  Units
MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
MyBenchmark.case07_WithSpringConfigLocationOption    ss   10  3.026 ± 0.139   s/op

Хм, это стало медленнее.

8. Выключите JMX

Бежал с -- Spring.jmx.включено=ложь :

Benchmark                                          Mode  Cnt  Score   Error  Units
MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
MyBenchmark.case08_WithJmxDisabledOption             ss   10  2.877 ± 0.097   s/op

Это стало немного быстрее.

9. Исключить Обратный вход

Отсюда я стараюсь исключить библиотеки. Сначала, исключая Обратный вход:

        
            org.springframework.boot
            spring-boot-starter-webflux
            
                
                    spring-boot-starter-logging
                    org.springframework.boot
                
            
        
        
            org.slf4j
            slf4j-jdk14
        

Вот результат:

Benchmark                                          Mode  Cnt  Score   Error  Units
MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
MyBenchmark.case09_WithoutLogback                    ss   10  2.904 ± 0.096   s/op

мм… немного улучшилось?

10. Исключить Джексона

Следующий – Джексон

        
            org.springframework.boot
            spring-boot-starter-webflux
            
                
                    spring-boot-starter-json
                    org.springframework.boot
                
            
        

Результат:

Benchmark                                          Mode  Cnt  Score   Error  Units
MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
MyBenchmark.case10_WithoutJackson                    ss   10  2.789 ± 0.093   s/op

Это стало немного быстрее.

11. Исключить Валидатор гибернации

        
            org.springframework.boot
            spring-boot-starter-webflux
            
                
                    hibernate-validator
                    org.hibernate.validator
                
            
        

Вот результат:

Benchmark                                          Mode  Cnt  Score   Error  Units
MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
MyBenchmark.case11_WithoutHibernateValidator         ss   10  2.857 ± 0.084   s/op

Тоже немного улучшилось.

Это конец исключения из библиотеки.

12. Атцдс

Компакт-диски приложений (Совместное использование данных класса приложений) были включены в Oracle JDK в качестве коммерческой функции. Но он стал доступен с OpenJDK 10.

Похоже, что AppCDS сбрасывает информацию в общий архив, поэтому время запуска сокращается.

Benchmark                                          Mode  Cnt  Score   Error  Units
MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
MyBenchmark.case12_WithAppCds                        ss   10  2.957 ± 0.079   s/op

мм… это было не быстрее… затем я проверил статьи о компакт-дисках и нашел причину.

С Spring Boot Fat JAR библиотеки выходят за рамки компакт-дисков.

13. Поток с тонкой пусковой установкой

Э-э, извините, но эталонное название “Взорвался” неверно. Однажды я попытался взорвать БАНКУ с Жиром, но в конце концов не смог использовать компакт-диски с взорванной БАНКОЙ. Поэтому я переключился на использование Тонкой пусковой установки. Пожалуйста, примите название эталона “Взорванный” как “Тонкая пусковая установка”.

Прежде чем использовать компакт-диски, я хотел бы проверить скорость файла JAR, упакованного с пусковой установкой.

        
            
                org.springframework.boot
                spring-boot-maven-plugin
                
                    
                        org.springframework.boot.experimental
                        spring-boot-thin-layout
                        1.0.15.RELEASE
                    
                
            
        

Хотя я использовал этот лаунчер для упаковки приложения, я не использовал класс запуска лаунчера, но указал Основной класс, чтобы максимально ускорить время запуска.

Benchmark                                          Mode  Cnt  Score   Error  Units
MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
MyBenchmark.case13_Exploded                          ss   10  2.476 ± 0.091   s/op

хм, немного быстрее, не так ли?

14. Тонкий лаунчер + компакт-диски

Теперь я хотел бы применить к нему APPCD.

Benchmark                                          Mode  Cnt  Score   Error  Units
MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
MyBenchmark.case14_ExplodedWithAppCds                ss   10  1.535 ± 0.036   s/op

Ух ты! Это стало намного быстрее!

15. Все применяемые

Наконец, я применил все.

Benchmark                                          Mode  Cnt  Score   Error  Units
MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
MyBenchmark.case15_AllApplied                        ss   10  0.801 ± 0.037   s/op

Менее 1 секунды! ( ∩∀’`∩ура

Еще один шаг

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

Список результатов

Benchmark                                          Mode  Cnt  Score   Error  Units
MyBenchmark.case01_FluxBaseline                      ss   10  2.938 ± 0.287   s/op
MyBenchmark.case02_Web                               ss   10  3.281 ± 0.342   s/op
MyBenchmark.case03_WithContextIndexer                ss   10  3.063 ± 0.102   s/op
MyBenchmark.case04_WithLazyInit                      ss   10  2.844 ± 0.129   s/op
MyBenchmark.case05_WithNoVerifyOption                ss   10  2.582 ± 0.060   s/op
MyBenchmark.case06_WithTieredStopAtLevel1Option      ss   10  1.980 ± 0.037   s/op
MyBenchmark.case07_WithSpringConfigLocationOption    ss   10  3.026 ± 0.139   s/op
MyBenchmark.case08_WithJmxDisabledOption             ss   10  2.877 ± 0.097   s/op
MyBenchmark.case09_WithoutLogback                    ss   10  2.904 ± 0.096   s/op
MyBenchmark.case10_WithoutJackson                    ss   10  2.789 ± 0.093   s/op
MyBenchmark.case11_WithoutHibernateValidator         ss   10  2.857 ± 0.084   s/op
MyBenchmark.case12_WithAppCds                        ss   10  2.957 ± 0.079   s/op
MyBenchmark.case13_Exploded                          ss   10  2.476 ± 0.091   s/op
MyBenchmark.case14_ExplodedWithAppCds                ss   10  1.535 ± 0.036   s/op
MyBenchmark.case15_AllApplied                        ss   10  0.801 ± 0.037   s/op

Это было действительно интересно. Спасибо!

Оригинал: “https://dev.to/bufferings/lets-make-springboot-app-start-faster-k9m”