我一直在为我的应用程序(在kubernetes中运行)进行(就绪)运行状况检查的实验。我以前进行过准备状况检查,该检查将检查应用程序是否可以连接到数据库并进行伪查询。但是,这不能确保应用程序可以实际插入数据库(例如,插入时出现权限问题)。为了解决这个问题,我编写了执行以下操作的代码:
除了回滚之外,上面的代码将按预期执行(意味着插入已成功执行以及读取,即使回滚期间也不会引发异常)。但是,回滚将以静默方式失败(因为记录仍显示在数据库中)。经过一番挖掘后,我相信jta事务绑定到了一个线程(https://docs.oracle.com/javaee/7/api/javax/transaction/UserTransaction.html),并且当我并行执行运行状况检查时,调用userTransaction的线程.begin()与调用userTransaction.rollback()的线程不同,如以下日志所示:
2020-09-16 02:25:57,519 WARN [com.arj.ats.arjuna] (pool-7-thread-1) ARJUNA012095: Abort of action id 0:ffffac110002:a243:5f617343:1 invoked while multiple threads active within it.
reading-comprehension | 2020-09-16 02:25:57,519 WARN [com.arj.ats.arjuna] (pool-7-thread-1) ARJUNA012381: Action id 0:ffffac110002:a243:5f617343:1 completed with multiple threads - thread pool-7-thread-1 was in progress with com.arjuna.ats.arjuna.coordinator.BasicAction.checkChildren(BasicAction.java:3407)
reading-comprehension | com.arjuna.ats.arjuna.coordinator.BasicAction.Abort(BasicAction.java:1667)
reading-comprehension | com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.cancel(TwoPhaseCoordinator.java:124)
reading-comprehension | com.arjuna.ats.arjuna.AtomicAction.abort(AtomicAction.java:186)
reading-comprehension | com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.rollbackAndDisassociate(TransactionImple.java:1369)
reading-comprehension | com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.rollback(BaseTransaction.java:143)
reading-comprehension | io.quarkus.narayana.jta.runtime.NarayanaJtaProducers_ProducerMethod_userTransaction_c93608e32f9c017c8aafd0401efc2eb68d35aa4e_ClientProxy.rollback(NarayanaJtaProducers_ProducerMethod_userTransaction_c93608e32f9c017c8aafd0401efc2eb68d35aa4e_ClientProxy.zig:177)
reading-comprehension | com.connor.reading.dao.AutoCloseableUserTransactionImpl.close(AutoCloseableUserTransactionImpl.java:27)
reading-comprehension | com.connor.reading.health.HealthCheckerInsertAssessmentImpl.getValue(HealthCheckerInsertAssessmentImpl.java:32)
reading-comprehension | com.connor.reading.health.HealthCheckerInsertAssessmentImpl_Subclass.getValue$$superaccessor3(HealthCheckerInsertAssessmentImpl_Subclass.zig:521)
reading-comprehension | com.connor.reading.health.HealthCheckerInsertAssessmentImpl_Subclass$$function$$3.apply(HealthCheckerInsertAssessmentImpl_Subclass$$function$$3.zig:29)
reading-comprehension | io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:54)
reading-comprehension | com.connor.reading.interceptor.DebugInterceptor.handleAroundInvoke(DebugInterceptor.java:32)
reading-comprehension | com.connor.reading.interceptor.DebugInterceptor_Bean.intercept(DebugInterceptor_Bean.zig:385)
reading-comprehension | io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)
reading-comprehension | io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:41)
reading-comprehension | io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:32)
reading-comprehension | com.connor.reading.health.HealthCheckerInsertAssessmentImpl_Subclass.getValue(HealthCheckerInsertAssessmentImpl_Subclass.zig:479)
reading-comprehension | com.connor.reading.health.HealthCheckerInsertAssessmentImpl.getValue(HealthCheckerInsertAssessmentImpl.java:13)
reading-comprehension | com.connor.reading.health.AbstractBaseHealthChecker.get(AbstractBaseHealthChecker.java:18)
reading-comprehension | com.connor.reading.health.HealthCheckerInsertAssessmentImpl_Subclass.get$$superaccessor2(HealthCheckerInsertAssessmentImpl_Subclass.zig:414)
reading-comprehension | com.connor.reading.health.HealthCheckerInsertAssessmentImpl_Subclass$$function$$2.apply(HealthCheckerInsertAssessmentImpl_Subclass$$function$$2.zig:29)
reading-comprehension | io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:54)
reading-comprehension | com.connor.reading.interceptor.DebugInterceptor.handleAroundInvoke(DebugInterceptor.java:32)
reading-comprehension | com.connor.reading.interceptor.DebugInterceptor_Bean.intercept(DebugInterceptor_Bean.zig:385)
reading-comprehension | io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)
reading-comprehension | io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:41)
reading-comprehension | io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:32)
reading-comprehension | com.connor.reading.health.HealthCheckerInsertAssessmentImpl_Subclass.get(HealthCheckerInsertAssessmentImpl_Subclass.zig:372)
reading-comprehension | com.connor.reading.health.AbstractBaseHealthChecker.get(AbstractBaseHealthChecker.java:5)
reading-comprehension | io.smallrye.context.SmallRyeThreadContext$ContextualCallable.call(SmallRyeThreadContext.java:116)
reading-comprehension | java.util.concurrent.FutureTask.run(FutureTask.java:264)
reading-comprehension | java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1128)
reading-comprehension | java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:628)
reading-comprehension | java.lang.Thread.run(Thread.java:834)
reading-comprehension | com.oracle.svm.core.thread.JavaThreads.threadStartRoutine(JavaThreads.java:517)
reading-comprehension | com.oracle.svm.core.posix.thread.PosixJavaThreads.pthreadStartRoutine(PosixJavaThreads.java:193)
reading-comprehension |
reading-comprehension | 2020-09-16 02:25:57,520 WARN [com.arj.ats.arjuna] (pool-7-thread-1) ARJUNA012381: Action id 0:ffffac110002:a243:5f617343:1 completed with multiple threads - thread executor-thread-1 was in progress with com.oracle.svm.core.posix.headers.Pthread.pthread_cond_timedwait(Pthread.java)
reading-comprehension | com.oracle.svm.core.posix.thread.PosixParkEvent.condTimedWait(PosixJavaThreads.java:271)
reading-comprehension | com.oracle.svm.core.thread.JavaThreads.park(JavaThreads.java:698)
reading-comprehension | jdk.internal.misc.Unsafe.park(Unsafe.java:53)
reading-comprehension | java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:234)
reading-comprehension | java.util.concurrent.FutureTask.awaitDone(FutureTask.java:444)
reading-comprehension | java.util.concurrent.FutureTask.get(FutureTask.java:203)
reading-comprehension | java.util.concurrent.AbstractExecutorService.invokeAll(AbstractExecutorService.java:284)
reading-comprehension | io.smallrye.context.SmallRyeManagedExecutor.invokeAll(SmallRyeManagedExecutor.java:118)
reading-comprehension | com.connor.reading.service.HealthService.executeChecksInParallel(HealthService.java:102)
reading-comprehension | com.connor.reading.service.HealthService_Subclass.executeChecksInParallel$$superaccessor10(HealthService_Subclass.zig:1528)
reading-comprehension | com.connor.reading.service.HealthService_Subclass$$function$$10.apply(HealthService_Subclass$$function$$10.zig:43)
reading-comprehension | io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:54)
reading-comprehension | com.connor.reading.interceptor.DebugInterceptor.handleAroundInvoke(DebugInterceptor.java:32)
reading-comprehension | com.connor.reading.interceptor.DebugInterceptor_Bean.intercept(DebugInterceptor_Bean.zig:385)
reading-comprehension | io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)
reading-comprehension | io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:41)
reading-comprehension | io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:32)
reading-comprehension | com.connor.reading.service.HealthService_Subclass.executeChecksInParallel(HealthService_Subclass.zig:1483)
reading-comprehension | com.connor.reading.service.HealthService.runHealthChecksInParallel(HealthService.java:84)
reading-comprehension | com.connor.reading.service.HealthService_Subclass.runHealthChecksInParallel$$superaccessor2(HealthService_Subclass.zig:614)
reading-comprehension | com.connor.reading.service.HealthService_Subclass$$function$$2.apply(HealthService_Subclass$$function$$2.zig:35)
reading-comprehension | io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:54)
reading-comprehension | com.connor.reading.interceptor.DebugInterceptor.handleAroundInvoke(DebugInterceptor.java:32)
reading-comprehension | com.connor.reading.interceptor.DebugInterceptor_Bean.intercept(DebugInterceptor_Bean.zig:385)
reading-comprehension | io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)
reading-comprehension | io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:41)
reading-comprehension | io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:32)
reading-comprehension | com.connor.reading.service.HealthService_Subclass.runHealthChecksInParallel(HealthService_Subclass.zig:571)
reading-comprehension | com.connor.reading.service.HealthService.checkDownstreamDependencies(HealthService.java:38)
reading-comprehension | com.connor.reading.service.HealthService_Subclass.checkDownstreamDependencies$$superaccessor3(HealthService_Subclass.zig:727)
reading-comprehension | com.connor.reading.service.HealthService_Subclass$$function$$3.apply(HealthService_Subclass$$function$$3.zig:33)
reading-comprehension | io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:54)
reading-comprehension | com.connor.reading.interceptor.DebugInterceptor.handleAroundInvoke(DebugInterceptor.java:32)
reading-comprehension | com.connor.reading.interceptor.DebugInterceptor_Bean.intercept(DebugInterceptor_Bean.zig:385)
reading-comprehension | io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)
reading-comprehension | io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:41)
reading-comprehension | io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:32)
reading-comprehension | com.connor.reading.service.HealthService_Subclass.checkDownstreamDependencies(HealthService_Subclass.zig:684)
reading-comprehension | com.connor.reading.controller.HealthApiImpl.readinessCheck(HealthApiImpl.java:32)
reading-comprehension | com.connor.reading.controller.HealthApiImpl_Subclass.readinessCheck$$superaccessor1(HealthApiImpl_Subclass.zig:223)
reading-comprehension | com.connor.reading.controller.HealthApiImpl_Subclass$$function$$1.apply(HealthApiImpl_Subclass$$function$$1.zig:33)
reading-comprehension | io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:54)
reading-comprehension | com.connor.reading.interceptor.DebugInterceptor.handleAroundInvoke(DebugInterceptor.java:32)
reading-comprehension | com.connor.reading.interceptor.DebugInterceptor_Bean.intercept(DebugInterceptor_Bean.zig:385)
reading-comprehension | io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:41)
reading-comprehension | io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:41)
reading-comprehension | io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:32)
reading-comprehension | com.connor.reading.controller.HealthApiImpl_Subclass.readinessCheck(HealthApiImpl_Subclass.zig:180)
reading-comprehension | java.lang.reflect.Method.invoke(Method.java:566)
reading-comprehension | org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:167)
reading-comprehension | org.jboss.resteasy.core.MethodInjectorImpl.invoke(MethodInjectorImpl.java:130)
reading-comprehension | org.jboss.resteasy.core.ResourceMethodInvoker.internalInvokeOnTarget(ResourceMethodInvoker.java:638)
reading-comprehension | org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTargetAfterFilter(ResourceMethodInvoker.java:504)
reading-comprehension | org.jboss.resteasy.core.ResourceMethodInvoker.lambda$invokeOnTarget$2(ResourceMethodInvoker.java:454)
reading-comprehension | org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)
reading-comprehension | org.jboss.resteasy.core.ResourceMethodInvoker.invokeOnTarget(ResourceMethodInvoker.java:456)
reading-comprehension | org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:417)
reading-comprehension | org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:391)
reading-comprehension | org.jboss.resteasy.core.ResourceMethodInvoker.invoke(ResourceMethodInvoker.java:68)
reading-comprehension | org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:488)
reading-comprehension | org.jboss.resteasy.core.SynchronousDispatcher.lambda$invoke$4(SynchronousDispatcher.java:259)
reading-comprehension | org.jboss.resteasy.core.SynchronousDispatcher.lambda$preprocess$0(SynchronousDispatcher.java:160)
reading-comprehension | org.jboss.resteasy.core.interception.jaxrs.PreMatchContainerRequestContext.filter(PreMatchContainerRequestContext.java:364)
reading-comprehension | org.jboss.resteasy.core.SynchronousDispatcher.preprocess(SynchronousDispatcher.java:163)
reading-comprehension | org.jboss.resteasy.core.SynchronousDispatcher.invoke(SynchronousDispatcher.java:245)
reading-comprehension | io.quarkus.resteasy.runtime.standalone.RequestDispatcher.service(RequestDispatcher.java:73)
reading-comprehension | io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.dispatch(VertxRequestHandler.java:132)
reading-comprehension | io.quarkus.resteasy.runtime.standalone.VertxRequestHandler.access$000(VertxRequestHandler.java:37)
reading-comprehension | io.quarkus.resteasy.runtime.standalone.VertxRequestHandler$1.run(VertxRequestHandler.java:94)
reading-comprehension | org.jboss.threads.ContextClassLoaderSavingRunnable.run(ContextClassLoaderSavingRunnable.java:35)
reading-comprehension | org.jboss.threads.EnhancedQueueExecutor.safeRun(EnhancedQueueExecutor.java:2046)
reading-comprehension | org.jboss.threads.EnhancedQueueExecutor$ThreadBody.doRunTask(EnhancedQueueExecutor.java:1578)
reading-comprehension | org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1452)
reading-comprehension | org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
reading-comprehension | org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
reading-comprehension | java.lang.Thread.run(Thread.java:834)
reading-comprehension | org.jboss.threads.JBossThread.run(JBossThread.java:479)
reading-comprehension | com.oracle.svm.core.thread.JavaThreads.threadStartRoutine(JavaThreads.java:517)
reading-comprehension | com.oracle.svm.core.posix.thread.PosixJavaThreads.pthreadStartRoutine(PosixJavaThreads.java:193)
reading-comprehension |
reading-comprehension | 2020-09-16 02:25:57,520 WARN [com.arj.ats.arjuna] (pool-7-thread-1) ARJUNA012108: CheckedAction::check - atomic action 0:ffffac110002:a243:5f617343:1 aborting with 2 threads active!
为证实我的怀疑,我将线程名称添加到日志中并找到以下内容:
reading-comprehension | 2020-09-16 02:25:57,516 INFO [com.con.rea.dao.AutoCloseableUserTransactionImpl] (executor-thread-1) Successfully started injected transaction (likely for health check). This was done on thread executor-thread-1
//logs omitted for breivy
reading-comprehension | 2020-09-16 02:25:57,521 INFO [com.con.rea.dao.AutoCloseableUserTransactionImpl] (pool-7-thread-1) Successfully rolled back transaction (likely for health check). This was done on thread pool-7-thread-1
存储库链接:https://gitlab.com/connorbutch/reading-comprehension/-/tree/9-list-all-assessments(确保您正在进行9-list-all-assessments分支)
(就绪)运行状况检查执行如下:
我已经想到了一些潜在的解决方案:
能否请您提供最佳解决方案的建议?