Жизненный цикл бина в Spring Boot 2.1 и Java 11 - PullRequest
0 голосов
/ 29 ноября 2018

Мой проект переходит с Spring Boot 2.0.4 с Java 8 на Spring Boot 2.1.0 с Java 11. Когда приложение было собрано с Spring Boot 2.0.4 и Java 8 и запущено в Docker / Docker Compose, *Был вызван метод, помеченный как 1001 *, но после перехода на Spring Boot 2.1.0 и Java 11 метод, помеченный как @PreDestroy, больше не вызывается.

Я попытался перейти от аннотаций к реализации InitializingBeanи DisposableBean, как описано здесь , но метод DisposableBean.destroy не вызывается.

Я также попытался добавить зависимость в javax.annotation-api версии 1.3.2 с помощьютот же результат.

Как воспроизвести:

Создать минимальное приложение Spring с bean-компонентом жизненного цикла:

import org.springframework.beans.factory.DisposableBean;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.stereotype.Component;

@Component
public class Life implements InitializingBean, DisposableBean {
    @Override
    public void destroy() throws Exception {
        System.out.println("--- Life.shutdown");
    }
    @Override
    public void afterPropertiesSet() throws Exception {
        System.out.println("--- Life.startup");
    }
}

Запустить приложение Spring из целевой подпапки:

cd target
java -jar demo-0.0.1-SNAPSHOT.jar

Когда приложение останавливается с помощью Ctrl + C, вызывается DisposableBean.destroy.

Возврат в родительскую папку:

cd ..

Запуск приложения Spring с использованием Maven:

mvn spring-boot:run

Когда приложение останавливается с помощью Ctrl + C, вызывается DisposableBean.destroy.

Dockerfile:

FROM openjdk:11.0.1-jre-slim
COPY target/*.jar app.jar
EXPOSE 8080
ENTRYPOINT java -jar /app.jar

Создание, запуск и остановка образа Docker:

docker build -t demo .
docker run -p 8080:8080 demo
docker ps
docker stats 3ca5b804ab13
docker stop 3ca5b804ab13
docker logs 3ca5b804ab13

Когда приложение останавливается с помощью Docker Stop, DisposableBean.destroy не вызывается.

docker-compose.yml:

demo:
  image: demo
  ports:
  - '8080:8080'

Запуск образа Docker с помощью Docker Compose (имитируетOpenShift):

docker-compose up
docker-compose down
demo_demo_1 exited with code 137

Когда приложение останавливается с помощью docker-compose down, DisposableBean.destroy не вызывается.

Я подозреваю, что Docker пытается выполнить SIGTERM, прежде чем он выдаст SIGKILLпотому что до уничтожения контейнера 10-секундная задержка.

Ответы [ 2 ]

0 голосов
/ 03 декабря 2018

Я думаю, что нашел решение (в этой записи в блоге ): используйте форму exec вместо формы оболочки в Dockerfile, чтобы SIGTERM, который выдает Docker, попадал в процесс java вместо процесса bash (которыйне пересылает сигналы никаким дочерним процессам).

  • Форма оболочки (выполняется с помощью оболочки / bin / sh -c): ENTRYPOINT java -jar /app.jar
  • Форма Exec (выполняется безоболочка): ENTRYPOINT ["java", "-jar", "/app.jar"]
0 голосов
/ 30 ноября 2018

Есть много мест, где установка может пойти не так.Во-первых, я предлагаю определить, есть ли какие-либо проблемы в части Java или Spring, или это проблема, связанная с докером / окружением.Судя по этому вопросу, это похоже на Java, но на самом деле я подозреваю, что это не в java / spring.

Итак, mvn spring-boot:run работает как положено, и я вижу, что вы упаковываете приложение весенней загрузки как jar (app.jar) скорее всего с плагином весенней загрузки.Это также место, где что-то может пойти не так, потому что весенняя загрузка использует специальный загрузчик классов для загрузки вещей во время выполнения.

Таким образом, чтобы полностью исключить часть «java / spring», перейдите в каталог target и запустите java -jar app.jar (конечно, убедитесь, что java 11 установлен на вашем локальном компьютере).Если это не сработает - исследуйте часть java / spring, в противном случае перейдите к части docker.

Скорее всего, приложение будет работать должным образом.

Теперь, как при настройке docker.Запустив docker compose и увидев, что он не работает,

Вы можете использовать следующие команды:

docker ps -a // -a flag to see container ids of containers that were stopped for whatever reason as well.

Теперь найдите Id завершившегося процесса Java и изучите его журналы:

docker logs <ID_OF_THE_EXTED_CONTAINER_GOES_HERE> 

Теперь есть вероятность, что контекст приложения не запускается (может быть, проблема, связанная с сетью, или что-то в этом роде, здесь действительно трудно определить, не видя фактического журнала), и, следовательно, проблема.

ДругойВозможная проблема в том, что приложение «слишком тяжелое» (под этим я подразумеваю, что оно превышает некоторые квоты, наложенные на Docker-контейнер).

Вы можете запустить команду docker stats <CONTAINER_ID>, чтобы увидеть ее использование памяти / процессора в режиме реального времени.или собирать метрики из приложения.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...