Производительность - Spring Boot - время ответа сервера
У меня странное поведение в нашем весеннем загрузочном приложении:
- Frontend/Client - угловой 6
- Backend - весенний ботинок - весна MVC - встроенный tomcat - Linux
После перезапуска бэкэнд первым вызовам контроллера требуется около 5 секунд, следующий запрос будет занимать только 50 мс. Это воспроизводится в 90% случаев, иногда даже первый вызов выполняется быстро.
Я уверен, проблема на сервере не на клиенте. В браузере я вижу, что время TTFB (время до первого байта) увеличивается до 5 секунд. Следующие запросы требуют только 10 мс для TTFB.
С инструментами мониторинга на сервере (динамика приложений) я могу собирать такие медленные вызовы сервера, а на графике вызовов я вижу, что:
org.apache.catalina.webresources.JarWarResourceSet:getArchiveEntries:117
требуется 4916 мс. Так вот, вот мое узкое место, я думаю. Но я не знаю, как это исправить.
Что я уже пробовал:
- Переключено с hikaricp в пул соединений apache tomcat jdbc
- Ugraded spring boot от 2.0.0 до 2.0.5
- Обновлен java до 1.8.0_181
- Propertie spring.jpa.tomcat.testOnBorrow = true
- Propertie spring.jpa.tomcat.validationQuery = выберите 1
Все без влияния на задержку сервера.
Обновить
Время утеряно, потому что файл войны сканируется несколько раз.
org.apache.catalina.webresources.CachedResource.validateResource проверяет, есть ли у нас файл войны (isPackedWarFile), и эта проверка возвращает false. Хотя это военный файл. Для этого плохого поведения у меня есть обходное решение. Я установил tomcat.resource.cache-tt в большое значение.
Но теперь org.apache.catalina.webresources.Cache.getResource имеет метод noCache. И в этом методе класс и файлы jar исключаются из кеширования. И вот почему файл войны снова проверяется.
Сканирование всего файла войны занимает примерно 5 секунд. И этот перерыв - это остановка мировой паузы. И это сканирование абсолютно бесполезно, потому что файл войны не взорван и поэтому его содержимое не может быть изменено.
Обновить
Если я поместил файл войны в установку tomcat, все будет быстро. Проблема с встроенным tomcat.
Ответы
Ответ 1
Я полагаю, вы уже это сделали, но если вы этого не сделали, взгляните на https://wiki.apache.org/tomcat/HowTo/FasterStartUp и внесите исправления, предлагаемые там.
Для отключения сканирования со встроенным tomcat в комментариях есть предложение: https://github.com/spring-projects/spring-boot/issues/1610
Если ни одно из приведенных выше рекомендаций не поможет вам исправить задержку, возможно, это будет первый запрос при запуске сервера (и запуск задержки оттуда).
@SpringBootApplication
public class Application implements CommandLineRunner {
@Autowired
private RestTemplate template;
public static void main (String args[]){
SpringApplication.run(Application.class, args);
}
@Override
public void run(String... strings) throws Exception {
// do an initial request from here to trigger scanning the war
template.exchange(...);
}
}
Таким образом, ваш клиент больше не будет испытывать задержку 5 с. Я знаю, что это взломать, поэтому, если вы найдете более чистый способ сделать это, используйте это вместо этого.
Ответ 2
Я столкнулся с аналогичной проблемой высокой загрузки процессора и задержки в ответе. org.apache.catalina.webresources.JarWarResourceSet:getArchiveEntries
занимала около 5 секунд во время сканирования файла войны. Во время сканирования запросы не подавались.
Я обновил Spring boot version
с 1.4.2.RELEASE
до 1.5.12.RELEASE
, которая разрешила эту проблему. Действительно, похоже, проблема связана со встроенным Tomcat
который исправлен в более поздних версиях.
Ответ 3
То, что вы описываете, является типичным эффектом перезагрузки в инфраструктуре, которая использует большой пул соединений с БД.
- первый запрос: откройте физическое соединение (от 100 мс до 2-3 секунд), выполните некоторую инициализацию (зависит от БД), выполните SQL (измените для каждого запроса), вернитесь в пул (<1 мс)
- второй запрос: извлечение из пула (<1 мс), выполнение SQL (для каждого запроса), возврат в пул (<1 мс)
основанный на ваших данных, я думаю, что первые два шага медленны и неспособны разогреть пул БД, вы будете испытывать очень медленные запросы. Потенциальные улучшения:
- настройте период разминки, в течение которого пул выполняет self-init, а Tomcat еще не отвечает
- проверьте на стороне БД, что делается при создании соединения и на стороне приложения, если/в какой конфигурации вы должны настроить соединение
Ответ 4
Использование исполняемого файла JAR (вместо WAR) для запуска со встроенным Tomcat решило проблему для меня. Это рекомендуемый способ для ускорения загрузки ресурсов из исполняемых архивов.
- вы можете иметь один проект Spring Boot и развертывать его как в JAR, так и в WAR,
- Мне пришлось переключиться с WAR на JAR, чтобы иметь лучшую производительность и возникла проблема при использовании JSP taglibs во freemarker. Это способ решить эту проблему при использовании JSP taglibs.
Ответ 5
Я думаю, вы должны добавить эти вещи для правильной работы весеннего сапога с помощью Angular 6:
- Добавление зависимостей в ваш
pom.xml
ниже:
=>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-undertow</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-tomcat</artifactId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
- Создайте файл
application.yml
в папке resources
проекта spring-boot и добавьте эти строки для настройки сервера tomcat:
=>
server:
port: 8082
undertow:
ioThreads: 15
workerThreads: 150
accesslog:
enabled: true
compression:
enabled: true
mimeTypes: text/xml, text/css, text/html, application/json
minResponseSize: 4096
spring:
application:
name: give the name of the spring boot project here
Примечание. Вы должны изменить minResponseSize, iothreads и workthreads в application.yml
. Значение по умолчанию для minResponseSize составляет 2048 байт. Здесь я изменил его на 4096 байт. Измените его соответствующим образом.
Спасибо :)
Это может вам помочь.