Проблема производительности Spring Boot с ClassLoader (XML DocumentBuilder / JSP) и исполняемым WAR - PullRequest
0 голосов
/ 19 марта 2019

В настоящее время мы перемещаем наше приложение в Spring Boot и сталкиваемся с проблемами производительности во время выполнения при запуске в качестве исполняемого файла WAR

Я создал пример проекта, чтобы легко воспроизвести его

git clone https://github.com/kicktipp/spring-jar-performance
cd spring-jar-performance
./mvnw clean package
java -jar target/spring-jar-performance.war

Теперь приложение работает.

while true; do ab -n 100 http://localhost:8080/ | grep longest; sleep 4; done

Результат выглядит странно:

 100%    307 (longest request)
 100%      2 (longest request)
 100%    305 (longest request)
 100%      1 (longest request)
 100%    331 (longest request)
 100%      2 (longest request)

Производительность довольно хорошая, но каждые несколько секунд один запрос отнимает возраст по сравнению с обычным поведением.Мы профилировали приложение и получили следующий результат: enter image description here

Таким образом, причина в этой строке в XmlController: (ссылка на Github)

DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();

Я не хочу винить в этом xerces XML Lib.Что происходит, так это то, что Xerces ищет путь к классу, и поэтому WebappClassLoaderBase ищет его в заархивированном файле WAR, который необходимо сначала распаковать.

Эта операция кэшируется, но каждые несколько секунд она повторяется.

Существует несколько сценариев, позволяющих избежать этой проблемы с производительностью.

  • Пакет как JAR
  • Использовать XOM как в XomController .

Мы не можем использовать исполняемый JAR, так как мы все еще используем некоторые JSP-файлы.Мы можем использовать XOM, но это не помогает в другой области:

У нас та же проблема с производительностью, когда проводится оценка JSP EL.При вычислении выражения типа ${myViewObject.name} происходит такая же загрузка классов.Это лучше как-то кешируется.Мы наблюдаем это только при первом вызове JSP.

Мы уже пытались добавить прекомпиляцию JSP в настройку, но это не помогает (это позволяет избежать времени компиляции, но не упомянутой здесь проблемы)

Поскольку наша WAR в производстве намного больше, чем эта тестовая WAR, для извлечения ZIP-файла и поиска класса в производстве требуется более 2 секунд.Это, конечно, не приемлемо для пользователя.

Это известная проблема для упаковки WAR с пружинной загрузкой?И если да, как мы можем это исправить / избежать?

...