<featureManager>
<feature>concurrent-3.0</feature>
</featureManager>
<managedExecutorService jndiName="concurrent/appTask">
<concurrencyPolicy max="2" maxQueueSize="5" runIfQueueFull="false" maxWaitForEnqueue="0" />
</managedExecutorService>
在弹簧文档(Https://docs.spring.io/spring-framework/reference/Reference/6.0/integration/scheduling.html#scheduling-scheduling-task-executor-types,Asscheduling.html#scheduling-task-executor-types)用于应用程序中的资源。我们的豆定义:
@Bean(name = "appTaskExecutor")
@Primary
TaskExecutor appJndiTaskExecutor() {
DefaultManagedTaskExecutor executor = new DefaultManagedTaskExecutor();
executor.setResourceRef(true);
executor.setJndiName("concurrent/appTask");
return executor;
}
然后我们在@Async(“ apptaskexecutor”)注释方法中使用ApptasKexecutor,该方法正在运行单个任务。因此,鉴于我们的托管ExecutorService定义在运行了7个连续任务后,执行人员服务将被充分占用,并将拒绝新任务。在春季文档(相同的链接)中,据说在这种情况下将抛出TaskEteDeDexception,因此我们正在捕获并处理事件。当我们使用CONCORJ运行应用程序服务器时,这一切都很好,但是当迁移到Liberty时,我们必须切换到Jakarta并发。我们得到的不是Task -RectectedException:
java.lang.IllegalStateException: java.lang.UnsupportedOperationException: isShutdown
at com.ibm.ws.concurrent.internal.ManagedExecutorServiceImpl.isShutdown(ManagedExecutorServiceImpl.java:710) ~[?:?]
at org.springframework.core.task.TaskRejectedException.executorDescription(TaskRejectedException.java:72) ~[spring-core-6.1.6.jar:6.1.6]
at org.springframework.core.task.TaskRejectedException.<init>(TaskRejectedException.java:66) ~[spring-core-6.1.6.jar:6.1.6]
at org.springframework.core.task.support.TaskExecutorAdapter.submit(TaskExecutorAdapter.java:132) ~[spring-core-6.1.6.jar:6.1.6]
at org.springframework.scheduling.concurrent.ConcurrentTaskExecutor$ManagedTaskExecutorAdapter.submit(ConcurrentTaskExecutor.java:221) ~[spring-context-6.1.6.jar:6.1.6]
at org.springframework.scheduling.concurrent.ConcurrentTaskExecutor.submit(ConcurrentTaskExecutor.java:172) ~[spring-context-6.1.6.jar:6.1.6]
at org.springframework.aop.interceptor.AsyncExecutionAspectSupport.$sw$original$doSubmit$m32m8m3(AsyncExecutionAspectSupport.java:297) ~[spring-aop-6.1.6.jar:6.1.6]
at org.springframework.aop.interceptor.AsyncExecutionAspectSupport.$sw$original$doSubmit$m32m8m3$accessor$$sw$vbmd262(AsyncExecutionAspectSupport.java) ~[spring-aop-6.1.6.jar:6.1.6]
at org.springframework.aop.interceptor.AsyncExecutionAspectSupport$$sw$auxiliary$1ncn2a1.call(Unknown Source) ~[spring-aop-6.1.6.jar:6.1.6]
at org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstMethodsInterWithOverrideArgs.intercept(InstMethodsInterWithOverrideArgs.java:85) ~[skywalking-agent.jar:9.3.0]
at org.springframework.aop.interceptor.AsyncExecutionAspectSupport.doSubmit(AsyncExecutionAspectSupport.java) ~[spring-aop-6.1.6.jar:6.1.6]
at org.springframework.aop.interceptor.AsyncExecutionInterceptor.invoke(AsyncExecutionInterceptor.java:127) ~[spring-aop-6.1.6.jar:6.1.6]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.6.jar:6.1.6]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768) ~[spring-aop-6.1.6.jar:6.1.6]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:720) ~[spring-aop-6.1.6.jar:6.1.6]
at org.ourCompany.ourApp.gateway.business.async.TaskJobManager$$SpringCGLIB$$0.processTask(<generated>) ~[ourApp-gateway-business-1.3.1.jar:?]
at org.ourCompany.ourApp.gateway.business.async.TaskQueueServiceBean.processTask(TaskQueueServiceBean.java:41) ~[ourApp-gateway-business-1.3.1.jar:1.3.1]
at jdk.internal.reflect.GeneratedMethodAccessor247.invoke(Unknown Source) ~[?:?]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
at java.base/java.lang.reflect.Method.invoke(Method.java:569) ~[?:?]
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:354) ~[spring-aop-6.1.6.jar:6.1.6]
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:196) ~[spring-aop-6.1.6.jar:6.1.6]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163) ~[spring-aop-6.1.6.jar:6.1.6]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768) ~[spring-aop-6.1.6.jar:6.1.6]
at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:123) ~[spring-tx-6.1.6.jar:6.1.6]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:392) ~[spring-tx-6.1.6.jar:6.1.6]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:119) ~[spring-tx-6.1.6.jar:6.1.6]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:184) ~[spring-aop-6.1.6.jar:6.1.6]
at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:768) ~[spring-aop-6.1.6.jar:6.1.6]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:720) ~[spring-aop-6.1.6.jar:6.1.6]
at org.ourCompany.ourApp.gateway.business.async.TaskQueueServiceBean$$SpringCGLIB$$0.processTask(<generated>) ~[ourApp-gateway-business-1.3.1.jar:?]
at org.ourCompany.ourApp.gateway.business.async.TaskSchedulerBean.processTasks(TaskSchedulerBean.java:30) ~[ourApp-gateway-business-1.3.1.jar:1.3.1]
at jdk.internal.reflect.GeneratedMethodAccessor246.invoke(Unknown Source) ~[?:?]
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[?:?]
at java.base/java.lang.reflect.Method.invoke(Method.java:569) ~[?:?]
at org.springframework.scheduling.support.ScheduledMethodRunnable.runInternal(ScheduledMethodRunnable.java:130) ~[spring-context-6.1.6.jar:6.1.6]
at org.springframework.scheduling.support.ScheduledMethodRunnable.lambda$run$2(ScheduledMethodRunnable.java:124) ~[spring-context-6.1.6.jar:6.1.6]
at io.micrometer.observation.Observation.observe(Observation.java:499) ~[micrometer-observation-1.12.5.jar:1.12.5]
at org.springframework.scheduling.support.ScheduledMethodRunnable.$sw$original$run$c8tpsq2(ScheduledMethodRunnable.java:124) ~[spring-context-6.1.6.jar:6.1.6]
at org.springframework.scheduling.support.ScheduledMethodRunnable.$sw$original$run$c8tpsq2$accessor$$sw$p2boiv3(ScheduledMethodRunnable.java) ~[spring-context-6.1.6.jar:6.1.6]
at org.springframework.scheduling.support.ScheduledMethodRunnable$$sw$auxiliary$afreg92.call(Unknown Source) ~[spring-context-6.1.6.jar:6.1.6]
at org.apache.skywalking.apm.agent.core.plugin.interceptor.enhance.InstMethodsInter.intercept(InstMethodsInter.java:86) ~[skywalking-agent.jar:9.3.0]
at org.springframework.scheduling.support.ScheduledMethodRunnable.run(ScheduledMethodRunnable.java) ~[spring-context-6.1.6.jar:6.1.6]
at org.springframework.scheduling.support.DelegatingErrorHandlingRunnable.run(DelegatingErrorHandlingRunnable.java:54) [spring-context-6.1.6.jar:6.1.6]
at java.base/java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:539) [?:?]
at java.base/java.util.concurrent.FutureTask.runAndReset(FutureTask.java:305) [?:?]
at java.base/java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:305) [?:?]
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1136) [?:?]
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:635) [?:?]
at java.base/java.lang.Thread.run(Thread.java:840) [?:?]
Caused by: java.lang.UnsupportedOperationException: isShutdown
... 50 more
这很有趣,因为它是在拨打taskeDrejectedexception.executordescription()之后从Libery中的ManagedExeCutorService实施的 - 因此,例外试图在春季之前抛出。我在Spring Core 6.1.6(Https://github.com/spring-projects/spring-framework/blob/blob/6.1.1.x/spring-core/src/src/src/src/main/main/java/java/springframefringframeframewrame-framewa/springframewramework- /core/task/taskrejectedexception.java
),这是有问题的方法:
private static String executorDescription(Executor executor) {
if (executor instanceof ExecutorService executorService) {
return "ExecutorService in " + (executorService.isShutdown() ? "shutdown" : "active") + " state";
} else {
return executor.toString();
}
}
问题在ExecutorService.isshutdown()
中。在所有Jakarta并发版本中(Https://jakarta.ee/specifications/concurrencations/3.0/jakarta-concurrency-spec-3.0.pdf)
The lifecycle of a ManagedExecutorService is managed by an application server. All lifecycle operations on the ManagedExecutorService interface will throw a java.lang.IllegalStateException exception. This includes the following methods that are defined in the java.util.concurrent.ExecutorService interface: awaitTermination(), isShutdown(), isTerminated(), shutdown(), and shutdownNow().
我将使用jakarta API而不是Spring使用服务器定义的托管ExeCutorService。
i我将增加可以并行运行的任务数量和任务队列,以便执行程序服务不会使Eashelly满满,我会弯曲Exection处理以匹配返回的驱逐(我不必说这确实是一个不典型的) .,我可以通过前两个解决方案来解决此问题,那里没问题。但是我很好奇我是否缺少某些东西,或者如果我没有选择并且需要使用自由中定义的托管executorService,我该怎么办。
i我怀疑当前
ManagedExecutorServiceImpl
Executor
的要求)获得一个代理,现在您可以获得整个对象。我怀疑春天还没有适应这一点。
绕过这一点,您可以做的是,而不是ExecutorService
设置aDefaultManagedTaskExecutor
只是处理查找的
DefaultManagedTaskExecutor
的扩展。您可以使用
ConcurrentTaskExecutor
手动进行查找,然后将其包裹在仅曝光DefaultManagedTaskExecutor
接口的代理中。
ConcurrentTaskExecutor
现在,将只有一个代理来实施JndiObjectFactoryBean
包装实际的托管执行人服务。现在,这将使检查失败并执行默认逻辑。