ускорьте время запуска spring boot

<p>у меня есть приложение spring boot. я добавил много зависимостей (к сожалению, все они мне нужны), и время запуска значительно возросло. просто выполнение <code>springapplication.run(source, args)</code> занимает 10 секунд. </p><p>хотя это не так уж много по сравнению с тем, к чему «привыкли», я недоволен тем, что это занимает так много, в основном потому, что это нарушает процесс разработки. само приложение на данный момент довольно маленькое, поэтому я предполагаю, что большую часть времени оно связано с добавленными зависимостями, а не с самими классами приложения.</p><p>я предполагаю, что проблема заключается в сканировании пути к классам, но я не уверен, как:</p><ul> <li>подтвердите, что это проблема (то есть, как «отладить» spring boot)</li> <li>если это действительно причина, как я могу ограничить ее, чтобы она стала быстрее? например, если я знаю, что какая-то зависимость или пакет не содержит ничего, что spring должен сканировать, есть ли способ ограничить это? </li> </ul><p>я предполагаю это:</p><ul> <li> <a href="https://jira.spring.io/browse/spr-8767">https://jira.spring.io/browse/spr-8767</a> </li> </ul><p>будет ускорять вещи, но это даже не сработало на этом этапе. я вижу некоторые другие усилия в самой spring boot, например:</p><ul> <li> <a href="https://github.com/spring-projects/spring-boot/issues/1610">https://github.com/spring-projects/spring-boot/issues/1610</a> </li> </ul><p>но это выглядит для tomcat.</p><p>эта статья:</p><ul> <li> <a href="http://www.nurkiewicz.com/2010/12/speeding-up-spring-integration-tests.html">http://www.nurkiewicz.com/2010/12/speeding-up-spring-integration-tests.html</a> </li> </ul><p>хотя он нацелен на интеграционные тесты, предлагает использовать <code>lazy-init=true</code>, однако я не знаю, как применить это ко всем bean-компонентам в spring boot с использованием конфигурации java - есть ли здесь какие-нибудь указатели?</p><p>любые (другие) предложения будут приветствоваться.</p>

<p>spring boot делает много автоматической настройки, которая может не потребоваться. поэтому вы можете захотеть сузить только автоконфигурацию, которая необходима для вашего приложения. чтобы увидеть полный список включенных автоконфигураций, просто запустите протоколирование <code>org.springframework.boot.autoconfigure</code> в режиме debug (<code>logging.level.org.springframework.boot.autoconfigure=debug</code> в <code>application.properties</code>). другой вариант - запустить приложение весенней загрузки с параметром <code>--debug</code>: <code>java -jar myproject-0.0.1-snapshot.jar --debug</code> </p><p>там будет что-то вроде этого в выводе:</p><pre><code>========================= auto-configuration report ========================= </code></pre><p>изучите этот список и включите только те автоконфигурации, которые вам нужны:</p><pre><code>@configuration @import({ dispatcherservletautoconfiguration.class, embeddedservletcontainerautoconfiguration.class, errormvcautoconfiguration.class, httpencodingautoconfiguration.class, httpmessageconvertersautoconfiguration.class, jacksonautoconfiguration.class, serverpropertiesautoconfiguration.class, propertyplaceholderautoconfiguration.class, thymeleafautoconfiguration.class, webmvcautoconfiguration.class, websocketautoconfiguration.class, }) public class samplewebuiapplication { </code></pre><p>код был скопирован из <a href="http://www.alexecollins.com/spring-boot-performance/">это сообщение в блоге</a> .</p>

<p>пока что голосование с наибольшим количеством голосов не является неправильным, но оно не идет вглубь, которую мне нравится видеть, и не дает никаких научных доказательств. команда spring boot выполнила упражнение по сокращению времени запуска boot 2.0, и в тикете <a href="https://github.com/spring-projects/spring-boot/issues/11226">11226</a> содержится много полезной информации. существует также билет <a href="https://github.com/spring-projects/spring-boot/issues/7939">7939</a> , открытый для добавления информации о времени к оценке состояния, но, похоже, у него нет конкретного eta.</p><p>наиболее полезный и методичный подход для отладки запуска загрузки был сделан дэйвом сайером. <a href="https://github.com/dsyer/spring-boot-startup-bench">https://github.com/dsyer/spring-boot-startup-bench</a> </p><p>у меня был похожий вариант использования, поэтому я воспользовался подходом дейва к микро-бенчмаркингу с jmh и побежал с ним. результатом является <a href="https://github.com/asarkar/spring/tree/master/boot-benchmark">boot-benchmark</a> project. я разработал его так, чтобы его можно было использовать для измерения времени запуска любого приложения spring boot, используя исполняемый файл jar, созданный <code>bootjar</code> (ранее называемый <code>bootrepackage</code> в boot 1.5) задачей gradle. не стесняйтесь использовать его и оставить отзыв.</p><p>мои выводы следующие:</p><ol> <li>цп имеет значение. много. </li> <li>запуск jvm с <a href="https://docs.oracle.com/javase/8/docs/technotes/tools/unix/java.html#babhdabi">-xverify: нет</a> помогает значительно.</li> <li>исключение ненужных автоконфигураций помогает.</li> <li>дейв рекомендовал аргумент jvm <a href="https://stackoverflow.com/questions/38721235/what-exactly-does-xx-tieredcompilation-do">-xx: tieredstopatlevel = 1</a> , но мои тесты не показали существенного улучшения с этим. кроме того, <code>-xx:tieredstopatlevel=1</code>, вероятно, замедлит ваш первый запрос.</li> <li>были <a href="http://blog.noizwaves.io/2017/09/02/slow-spring-boot-startup.html">отчеты</a> разрешения имени хоста были медленными, но я не обнаружил, что это является проблемой для приложений, которые я тестировал.</li> </ol>

<p>как описано в этом вопросе/ответе, я думаю, что лучший подход состоит в том, чтобы вместо добавления только тех, которые, по вашему мнению, вам нужны, исключить зависимости, которые, как вы знаете, вам не нужны.</p><p>смотрите: <a href="https://stackoverflow.com/questions/35709234/minimise-spring-boot-startup-time/35713866#35713866">минимизируйте время запуска весенней загрузки</a> </p><p>в итоге:</p><p>вы можете увидеть, что происходит под одеялом, и включить ведение журнала отладки так же просто, как указать --debug при запуске приложения из командной строки. вы также можете указать debug = true в вашем application.properties.</p><p>кроме того, вы можете установить уровень ведения журнала в application.properties так же просто, как:</p><p>logging.level.org.springframework.web: debug logging.level.org.hibernate: ошибка</p><p>если вы обнаружите автоматически настроенный модуль, который вам не нужен, его можно отключить. документы для этого можно найти здесь: <a href="http://docs.spring.io/spring-boot/docs/current-snapshot/reference/htmlsingle/#using-boot-disabling-specific-auto-configuration">http://docs.spring.io/spring-boot/docs/current-snapshot/reference/htmlsingle/#using-boot-disabling-specific-auto-configuration</a> </p><p>пример будет выглядеть так:</p><pre><code>@configuration @enableautoconfiguration(exclude={datasourceautoconfiguration.class}) public class myconfiguration { } </code></pre>

<p><strong> spring boot 2.2.m1 </strong>добавил функцию для поддержки отложенной инициализации в spring boot.</p><p>по умолчанию при обновлении контекста приложения создается каждый компонент в контексте и внедряются его зависимости. напротив, когда определение bean-компонента сконфигурировано для ленивой инициализации, оно не будет создано, и его зависимости не будут внедрены до тех пор, пока это не понадобится.</p><p><strong> включение отложенной инициализации </strong>установите <code>spring.main.lazy-initialization</code> в<strong> true </strong></p><p>для более подробной информации, пожалуйста, проверьте <a href="https://spring.io/blog/2019/03/14/lazy-initialization-in-spring-boot-2-2">док</a> </p>

<p>если вы пытаетесь оптимизировать процесс разработки для ручного тестирования, я настоятельно рекомендую использовать <a href="https://docs.spring.io/spring-boot/docs/current/reference/html/using-boot-devtools.html">devtools</a> .</p><blockquote> <p>приложения, использующие spring-boot-devtools, автоматически перезапустятся всякий раз, когда файлы на пути к классам меняются.</p> </blockquote><p>просто перекомпилируйте - и сервер перезагрузится сам (для groovy вам нужно только обновить исходный файл). если вы используете ide (например, «vscode»), он может автоматически компилировать ваши файлы java, поэтому простое сохранение файла java может инициировать перезапуск сервера, косвенно - и java становится такой же цельной, как groovy в это отношение.</p><p><em>прелесть этого подхода в том, что при постепенном перезапуске происходит короткое замыкание на некоторых этапах запуска с нуля, поэтому ваша служба будет работать быстрее и быстрее!</em></p><hr><p>к сожалению, это не помогает со временем запуска для развертывания или автоматического модульного тестирования.</p>