Производительность - Spring Boot - Время отклика сервера - PullRequest
0 голосов
/ 04 октября 2018

У меня странное поведение в нашем приложении весенней загрузки:

  • Фронтенд / клиент - угловой 6
  • Бэкэнд - пружинная загрузка - пружина 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

Все, что не влияет на задержку сервера.

Обновление

Время потеряно из-за многократного сканирования файла войныtimes.

org.apache.catalina.webresources.CachedResource.validateResource проверяет, есть ли у нас файл войны ( isPackedWarFile ), и эта проверка возвращает false.Хотя это файл войны.Для этого плохого поведения у меня есть обходной путь.Я установил tomcat.resource.cache-tt на высокое значение.

Но теперь org.apache.catalina.webresources.Cache.getResource имеет метод noCache .И в этом методе файлы class и jar исключаются из кэширования.Именно по этой причине файл war снова сканируется.

Сканирование всего файла war занимает примерно 5 секунд.И этот перерыв - остановка мирового прорыва.И это сканирование абсолютно не нужно, потому что файл войны не взорван и поэтому его содержимое не может быть изменено.

Обновление

Если я помещу файл войны в котаустановка все быстро.Проблема во встроенном коте.

Ответы [ 3 ]

0 голосов
/ 15 октября 2018

То, что вы описываете, - это типичное влияние перезагрузки на инфраструктуру, в которой используется интенсивный пул соединений с БД.

  • первый запрос: откройте физическое соединение (от 100 мс до 2-3 с),выполнить некоторую инициализацию (зависит от БД), выполнить SQL (зависит от запроса), вернуться в пул (<1 мс) </li>
  • второй запрос: извлечь из пула (<1 мс), выполнить SQL (изменить для запроса), вернутьк пулу (<1 мс) </li>

на основе ваших данных, я думаю, что первые два шага медленны и до тех пор, пока пул БД не прогреется, у вас возникнут очень медленные запросы.Потенциальные улучшения:

  • настройка периода прогрева, в течение которого пул выполняет самоинициацию, пока Tomcat еще не отвечает
  • проверка на стороне БД, что делается при создании соединенияи на стороне приложения, если / какой конфигурации вы должны настроить соединение
0 голосов
/ 22 октября 2018

Я столкнулся с похожей проблемой высокой загрузки ЦП и задержкой ответа.org.apache.catalina.webresources.JarWarResourceSet:getArchiveEntries занимало около 5 секунд при сканировании файла войны. Во время сканирования запросы не обрабатывались.

Я обновил Spring boot version с 1.4.2.RELEASE до 1.5.12.RELEASE, что решило эту проблему.Действительно, похоже, проблема была со встроенным Tomcat, который был исправлен в более поздних версиях.

0 голосов
/ 12 октября 2018

Я полагаю, что вы уже сделали, но если вы этого не сделали, взгляните на 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 секунд.Я знаю, что это взлом, поэтому, если вы найдете более чистый способ сделать это, используйте его вместо этого.

...