Приложение Springboot не отвечает после запланированного запуска cron - PullRequest
0 голосов
/ 26 марта 2020

У меня есть служба Springboot с @Scheduled cron, запущенной в 2:30. Во время запуска cron я пытаюсь выполнить некоторые операции с БД, которые извлекают много данных из памяти, и при извлечении набора результатов я сталкиваюсь с ошибкой кучи Java. Тем не менее, поскольку это происходит в потоке scheduling-1, я ожидаю, что мое приложение Springboot будет работать нормально и отвечать на запросы проверки работоспособности, как и ожидалось.

Однако (в большинстве случаев, НЕ ВСЕ) это происходит:

  1. Приложение Springboot перестает отвечать на запросы проверки работоспособности. Он перестает отвечать на любые запросы CURL.
  2. Однако другие мои кроны, которые впоследствии выполняются в потоке scheduling-1, работают успешно.
  3. Я использую почасовую политику logrotate для записи в журналы. Я вижу, что приложение Springboot (кроме потока scheduled-1) прекращает запись в журналы, файлы журналов создаются только в часы, в которые запланированы некоторые кроны. В остальные часы файлы журнала отсутствуют. Так, например, текущие файлы журнала, которые у меня есть на сегодня, application.2020-03-26_00.0.log application.2020-03-26_01.0.log application.2020-03-26_02.0.log application.2020-03-26_04.0.log application.2020-03-26_06.0.log. Вы можете видеть, как нет журнала для 3 и 5 часов утра, потому что в 4 часа утра и в 6 часов утра были запущены кроны.
  4. Когда я запускаю lsof -i : 8080, чтобы посмотреть, по-прежнему ли мой сервис слушает это порт (учитывая, что он дает сбой Connection reset by peer на любом CURL), я получаю следующий вывод.
COMMAND   PID   USER   FD   TYPE   DEVICE SIZE/OFF NODE NAME
java    24980 deploy  475u  IPv4 79544043      0t0  TCP *:http-alt (LISTEN)
java    24980 deploy  601u  IPv4 80098922      0t0  TCP ip-x-x-x-x.ap-southeast-1.compute.internal:http-alt->ip-x-x-x-x.ap-southeast-1.compute.internal:30616 (CLOSE_WAIT)

Принимая во внимание, что в другом окне, на котором cron в 2:30 AM не работал и работает исправно, эта же команда lsof возвращает следующее:

COMMAND   PID   USER   FD   TYPE   DEVICE SIZE/OFF NODE NAME
java    28975 deploy  184u  IPv4 71997654      0t0  TCP ip-x-x-x-x.ap-southeast-1.compute.internal:http-alt->ip-x-x-x-x.ap-southeast-1.compute.internal:58560 (ESTABLISHED)
java    28975 deploy  198u  IPv4 72011154      0t0  TCP ip-x-x-x-x.ap-southeast-1.compute.internal:http-alt->ip-x-x-x-x.ap-southeast-1.compute.internal:51588 (ESTABLISHED)
java    28975 deploy  278u  IPv4 72010749      0t0  TCP ip-x-x-x-x.ap-southeast-1.compute.internal:http-alt->ip-x-x-x-x.ap-southeast-1.compute.internal:41256 (ESTABLISHED)
java    28975 deploy  484u  IPv4 71536371      0t0  TCP *:http-alt (LISTEN)

Как вы можете видеть, на поле, где приложение не отвечает на веб-запросы, есть только одно прослушивающее соединение и одно соединение в состоянии CLOSE_WAIT, где, как и в работоспособном окне, есть 3 УСТАНОВЛЕННЫХ соединения.

Наконец, это происходит только в 90% случаев. Остальные 10%, служба, в которой cron запустился в 2:30 и вызвала исключение JDB C, продолжает нормально функционировать. Это делает ситуацию еще более загадочной.

Может кто-нибудь помочь мне понять, почему в затронутой коробке нет установленных соединений. Кроме того, может ли исключение JDB C в потоке scheduling-1 вызывать эту проблему? Тогда почему поток shceduling-1 может успешно запускать другие кроны?

Вот соответствующая часть трассировки стека исключения JDB, если это помогает:

com.zaxxer.hikari.pool.ProxyConnection:153 - HikariPool-1 - Connection com.mysql.cj.jdbc.ConnectionImpl@4fa3351a marked as broken because of SQLSTATE(08007), ErrorCode(0)
java.sql.SQLNonTransientConnectionException: Communications link failure during rollback(). Transaction resolution unknown.
        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:110)
        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:97)
        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:89)
        at com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:63)
        at com.mysql.cj.jdbc.ConnectionImpl.rollback(ConnectionImpl.java:1846)
        at com.zaxxer.hikari.pool.ProxyConnection.rollback(ProxyConnection.java:370)
        at com.zaxxer.hikari.pool.HikariProxyConnection.rollback(HikariProxyConnection.java)
        at org.hibernate.resource.jdbc.internal.AbstractLogicalConnectionImplementor.rollback(AbstractLogicalConnectionImplementor.java:116)
        at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.rollback(JdbcResourceLocalTransactionCoordinatorImpl.java:294)
        at org.hibernate.engine.transaction.internal.TransactionImpl.rollback(TransactionImpl.java:145)
        at org.springframework.orm.jpa.JpaTransactionManager.doRollback(JpaTransactionManager.java:559)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.processRollback(AbstractPlatformTransactionManager.java:838)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.rollback(AbstractPlatformTransactionManager.java:812)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.completeTransactionAfterThrowing(TransactionAspectSupport.java:552)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:299)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:144)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$ExposeRepositoryInvocationInterceptor.invoke(CrudMethodMetadataPostProcessor.java:364)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:93)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
        at com.sun.proxy.$Proxy218.deleteAll(Unknown Source)
...