Почему Micrometer не перестает отправлять данные в datadog и просто закрывается?

У меня есть приложение Spring Boot, которое из-за странных ограничений должно запускаться каждые три часа и не будет работать с Quartz, поэтому я запускал его каждые три часа из cron ОС, и он закрывается, когда он готов. Однако после добавления micrometer-registry-datadog (и spring-legacy) он никогда не завершает работу, он просто отправляет метрики каждые 20 секунд или независимо от периода по умолчанию, даже после вызова registry.close ().

Обречен ли я, как голландец, вечно плыть по морям обработки, или я совершил очевидную ошибку?

Код: он достигает SpringApplication.exit (ctx), но на самом деле не завершается чисто. (сервис - это TimedExecutorService.)

        public void close() throws InterruptedException {
            service.shutdown();
            service.awaitTermination(Long.MAX_VALUE, TimeUnit.NANOSECONDS);
            meterRegistry.close();
            SpringApplication.exit(ctx);
    }
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Версия Java на основе версии загрузки
Версия Java на основе версии загрузки
Если вы зайдете на официальный сайт Spring Boot , там представлен start.spring.io , который упрощает создание проектов Spring Boot, как показано ниже.
Документирование API с помощью Swagger на Springboot
Документирование API с помощью Swagger на Springboot
В предыдущей статье мы уже узнали, как создать Rest API с помощью Springboot и MySql .
0
0
554
1

Ответы 1

Это похоже на ошибку. Возможно, экспортер Datadog работает в не-демоническом потоке. JVM рассматривает потоки, не являющиеся демонами, как критически важную работу для приложения.

По сути, JVM считает, что не следует отключаться, пока не завершится не-демонический поток. В случае с веткой экспортера Datadog этого, вероятно, не произойдет.

Чтобы проверить наличие потоков, не являющихся демонами, используйте jstack для создания дампа потока. (команда: jstack <pid>) или выгрузите все потоки в вашем методе close:

ThreadMXBean threadMxBean = ManagementFactory.getThreadMXBean();
for (ThreadInfo ti : threadMxBean.dumpAllThreads(true, true)) {
  System.out.print(ti.toString());
}

Ниже приведен пример вывода дампа потока. Обратите внимание на слово «демон» в первой строке:

"pool-1-thread-1" #13 prio=5 os_prio=31 tid=0x00007fe885aa5000 nid=0xa907 waiting on condition [0x000070000d67b000]
   java.lang.Thread.State: WAITING (parking)
    at sun.misc.Unsafe.park(Native Method)
    - parking to wait for  <0x00000006c07e9720> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject)
    at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175)
    at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039)
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1081)
    at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809)
    at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1074)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1134)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

Включая дамп потока, который я не могу прочитать ... dropbox.com/s/5dwuzeqpmbp1qss/stacktrace.txt?dl=0 Один поток, не являющийся демоном, торчит, пул-1-поток-1, похоже, ожидает блокировки параллелизма, что может быть связано с тем, что я использовал DataDog для его измерения. .. Никогда даже не задумывался об этом аспекте ...

tofagerl 04.05.2018 13:56

Кажется, виновата эта нить. Я ожидал, что экспортер Datadog назовет себя более полезным. Это очищается с помощью метода meterRegistry.close (). Какой тип реестра счетчиков вы закрываете в образце кода?

checketts 04.05.2018 19:15

DatadogMeterRegistry. И я, конечно, вызвал close (), он просто не работает так, как мне хотелось бы.

tofagerl 07.05.2018 09:20

Другие вопросы по теме