如何定时触发自己的端点?

问题描述 投票:0回答:1

我有一个调用某些函数的现有端点,并且在对端点进行休息调用时工作正常。然后我想创建一个调度程序来定期调用该函数。调度程序本身按预期工作,但现在在调度函数期间函数出现意外异常。端点的其余部分仍然有效。由于问题似乎是 RequestScoped bean,我尝试了ActivateRequestContent,但没有任何变化。

下面是最低限度可重现的示例,可以更好地解释问题。

编辑:我不想修改服务或某些外部 cron。我希望解决方案位于 Scheduler 中。

我有资源:

@Path("/hello")
public class GreetingResource {

    @Inject
    GreetingService greetingService;

    @GET
    public String hello() {
        return greetingService.getGreetings();
    }
}

服务:

@ApplicationScoped
public class GreetingService {

    @Inject
    RequestBean requestBean;

    public String getGreetings() {

        //do logic, call other services, save to DB, etc

        if (requestBean.getAcceptLanguage().equals("en")) {
            return "Hello from RESTEasy Reactive";
        } else {
            return "Hola desde RESTEasy Reactive";
        }
    }
}

还有一个 RequestScoped bean。

@RequestScoped
public class RequestBean {

    private String acceptLanguage;

    RequestBean(HttpHeaders httpHeaders) {
        acceptLanguage = httpHeaders.getHeaderString(HttpHeaders.ACCEPT_LANGUAGE);
        if (acceptLanguage == null || acceptLanguage.isBlank()) {
            this.acceptLanguage = "en";
        }
    }

    public String getAcceptLanguage() {
        return acceptLanguage;
    }
}

端点在 test 和 postman 中工作。

但现在我需要定期做同样的工作。

所以我添加了调度程序。

@ApplicationScoped
public class Scheduler {

    @Inject
    GreetingService greetingService;

    @Scheduled(every = "10s")
    @ActivateRequestContext
    public void scheduledTask() {

        try {
            Log.info("Scheduler is starting");
            greetingService.getGreetings();
            Log.info("Scheduler is finished");
        } catch (Exception e) {
            Log.error("Error while running scheduler", e);
        }

    }
}

我预计不会有异常,但我在 ScheduledTask 中遇到异常。

java.lang.IllegalStateException: No RESTEasy Reactive request in progress
        at org.jboss.resteasy.reactive.server.injection.ContextProducers.getContext(ContextProducers.java:149)
        at org.jboss.resteasy.reactive.server.injection.ContextProducers.headers(ContextProducers.java:52)
        at org.jboss.resteasy.reactive.server.injection.ContextProducers_ProducerMethod_headers_VA74pGGn-tu4h7_tlI2NceCHbzU_Bean.doCreate(Unknown Source)
        at org.jboss.resteasy.reactive.server.injection.ContextProducers_ProducerMethod_headers_VA74pGGn-tu4h7_tlI2NceCHbzU_Bean.create(Unknown Source)
        at org.jboss.resteasy.reactive.server.injection.ContextProducers_ProducerMethod_headers_VA74pGGn-tu4h7_tlI2NceCHbzU_Bean.create(Unknown Source)
        at io.quarkus.arc.impl.RequestContext$1.get(RequestContext.java:79)
        at io.quarkus.arc.impl.RequestContext$1.get(RequestContext.java:75)
        at io.quarkus.arc.generator.Default_jakarta_enterprise_context_RequestScoped_ContextInstances.c2(Unknown Source)
        at io.quarkus.arc.generator.Default_jakarta_enterprise_context_RequestScoped_ContextInstances.computeIfAbsent(Unknown Source)
        at io.quarkus.arc.impl.RequestContext.getIfActive(RequestContext.java:75)
        at io.quarkus.arc.impl.ClientProxies.getSingleContextDelegate(ClientProxies.java:28)
        at jakarta.ws.rs.core.ContextProducers_ProducerMethod_headers_VA74pGGn-tu4h7_tlI2NceCHbzU_ClientProxy.arc$delegate(Unknown Source)
        at jakarta.ws.rs.core.ContextProducers_ProducerMethod_headers_VA74pGGn-tu4h7_tlI2NceCHbzU_ClientProxy.getHeaderString(Unknown Source)
        at com.example.RequestBean.<init>(RequestBean.java:12)
        at com.example.RequestBean_Bean.doCreate(Unknown Source)
        at com.example.RequestBean_Bean.create(Unknown Source)
        at com.example.RequestBean_Bean.create(Unknown Source)
        at io.quarkus.arc.impl.RequestContext$1.get(RequestContext.java:79)
        at io.quarkus.arc.impl.RequestContext$1.get(RequestContext.java:75)
        at io.quarkus.arc.generator.Default_jakarta_enterprise_context_RequestScoped_ContextInstances.c0(Unknown Source)
        at io.quarkus.arc.generator.Default_jakarta_enterprise_context_RequestScoped_ContextInstances.computeIfAbsent(Unknown Source)
        at io.quarkus.arc.impl.RequestContext.getIfActive(RequestContext.java:75)
        at io.quarkus.arc.impl.ClientProxies.getSingleContextDelegate(ClientProxies.java:28)
        at com.example.RequestBean_ClientProxy.arc$delegate(Unknown Source)
        at com.example.RequestBean_ClientProxy.getAcceptLanguage(Unknown Source)
        at com.example.GreetingService.getGreetings(GreetingService.java:16)
        at com.example.GreetingService_ClientProxy.getGreetings(Unknown Source)
        at com.example.Scheduler.scheduledTask(Scheduler.java:21)
        at com.example.Scheduler_Subclass.scheduledTask$$superforward(Unknown Source)
        at com.example.Scheduler_Subclass$$function$$1.apply(Unknown Source)
        at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:73)
        at io.quarkus.arc.impl.AroundInvokeInvocationContext.proceed(AroundInvokeInvocationContext.java:62)
        at io.quarkus.arc.impl.ActivateRequestContextInterceptor.invoke(ActivateRequestContextInterceptor.java:124)
        at io.quarkus.arc.impl.ActivateRequestContextInterceptor.aroundInvoke(ActivateRequestContextInterceptor.java:33)
        at io.quarkus.arc.impl.ActivateRequestContextInterceptor_Bean.intercept(Unknown Source)
        at io.quarkus.arc.impl.InterceptorInvocation.invoke(InterceptorInvocation.java:42)
        at io.quarkus.arc.impl.AroundInvokeInvocationContext.perform(AroundInvokeInvocationContext.java:30)
        at io.quarkus.arc.impl.InvocationContexts.performAroundInvoke(InvocationContexts.java:27)
        at com.example.Scheduler_Subclass.scheduledTask(Unknown Source)
        at com.example.Scheduler_ClientProxy.scheduledTask(Unknown Source)
        at com.example.Scheduler_ScheduledInvoker_scheduledTask_b06a23f86c5479393959068a663c2a2a98c84093.invokeBean(Unknown Source)
        at io.quarkus.scheduler.common.runtime.DefaultInvoker.invoke(DefaultInvoker.java:24)
        at io.quarkus.scheduler.common.runtime.StatusEmitterInvoker.invoke(StatusEmitterInvoker.java:35)
        at io.quarkus.scheduler.runtime.SimpleScheduler$ScheduledTask.doInvoke(SimpleScheduler.java:443)
        at io.quarkus.scheduler.runtime.SimpleScheduler$ScheduledTask$2.call(SimpleScheduler.java:425)
        at io.quarkus.scheduler.runtime.SimpleScheduler$ScheduledTask$2.call(SimpleScheduler.java:422)
        at io.vertx.core.impl.ContextImpl.lambda$executeBlocking$0(ContextImpl.java:178)
        at io.vertx.core.impl.ContextInternal.dispatch(ContextInternal.java:279)
        at io.vertx.core.impl.ContextImpl.lambda$internalExecuteBlocking$2(ContextImpl.java:210)
        at org.jboss.threads.ContextHandler$1.runWith(ContextHandler.java:18)
        at org.jboss.threads.EnhancedQueueExecutor$Task.run(EnhancedQueueExecutor.java:2513)
        at org.jboss.threads.EnhancedQueueExecutor$ThreadBody.run(EnhancedQueueExecutor.java:1512)
        at org.jboss.threads.DelegatingRunnable.run(DelegatingRunnable.java:29)
        at org.jboss.threads.ThreadLocalResettingRunnable.run(ThreadLocalResettingRunnable.java:29)
        at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
        at java.base/java.lang.Thread.run(Thread.java:1583)

相关依赖:

<quarkus.platform.version>3.8.5</quarkus.platform.version>
...
<dependency>
   <groupId>io.quarkus</groupId>
   <artifactId>quarkus-resteasy-reactive-jackson</artifactId>
</dependency>
<dependency>
   <groupId>io.quarkus</groupId>
   <artifactId>quarkus-scheduler</artifactId>
</dependency>

编辑2: 解决方案确实有效,但不太好。

  1. 返工服务 -> 服务量很大,没有时间。
  2. 外部 cron 作业调用工作端点 -> 我无法控制外部应用程序,授权问题
  3. 使用curl我的端点调用shell -> 看起来很奇怪,授权问题
  4. 在调度程序中使用测试代码
given()
   .when()
   .get("/hello")
   .then()
   .statusCode(200);

-> 与 1-3 种解决方案相比,这看起来非常好,但在主代码中放心导入感觉是错误的。是不是搞错了?

quarkus scheduler reactive requestscope
1个回答
0
投票

您可以尝试使用 Quarkus RestClient 访问 /hello 路径。如果您需要处理身份验证,您可以执行以下操作:

访问API的类

import com.fasterxml.jackson.databind.JsonNode;
import jakarta.ws.rs.*;
import org.eclipse.microprofile.rest.client.inject.RegisterRestClient;

@RegisterRestClient
public interface Api {
    @GET
    @Path("/hello")
    JsonNode hello(@HeaderParam("Authorization") String token);
}

然后是你预定的事情

@RestClient
Api api;
@Scheduled(every = "10s")
void doTheJob(){
  String token;
  // do something to get the token
  api.hello(token);
}
© www.soinside.com 2019 - 2024. All rights reserved.