有没有更好的方法来只允许一个并发的骆驼路由执行并在路由运行时丢弃额外的请求?

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

目标:

  • 我想跑骆驼路线,需要很长时间才能完成。我想要 使用 put 请求启动此路由。
  • 我只想允许 1 个并发 该路线的处决。
  • 我想放弃任何其他请求 路线仍在处理中时到达。我不想让他们排队 稍后处理,直接丢弃。

在尝试了我能想到的所有方法之后,我最终得到了以下代码,该代码使用 AtomicBoolean 来记住当前是否正在处理某些内容。但这对我来说似乎有点黑客。鉴于上述要求,我应该这样解决它还是骆驼提供任何更好的方法?

@Component
public class TestRoute2 extends RouteBuilder {

  @Autowired
  private MyService myService;

  @Override
  public void configure() {

    AtomicBoolean isProcessing = new AtomicBoolean(false);

    from("platform-http:/api/myservice?httpMethodRestrict=PUT")
      .routeId("myServiceRoute")
      .doTry()
        .process(exchange -> {
        // Cast the endpoint to SedaEndpoint to access the queue
        SedaEndpoint sedaEndpoint = (SedaEndpoint)
        getContext().getEndpoint("seda:handlePut");
        int currentQueueSize = sedaEndpoint
          .getQueue()
          .size();

        if (currentQueueSize > 0 || isProcessing.get()) {
          throw new org.apache.camel.CamelExchangeException("Service busy", exchange);
        }

        // Mark service as busy
        isProcessing.set(true);
      })
        .wireTap("seda:handlePut")
        .setHeader("CamelHttpResponseCode", constant(204))
      .endDoTry()
      .doCatch(org.apache.camel.CamelExchangeException.class)
      .setHeader("CamelHttpResponseCode", constant(503))
      .setBody(constant("Service busy, please try again later"))
      .end();

    from("seda:handlePut?concurrentConsumers=1")
      .doTry()
        .bean(myService, "slowMethod") // runs for long time
      .endDoTry()
      .doFinally()
      .process(exchange -> isProcessing.set(false));
  }
}

在此之前我也尝试过以下代码。它不使用 AtomicBoolean,从干净的代码角度来看这似乎有所改进,但问题是它在开始返回 503 之前仍然会排队 1 个额外的请求。这意味着在handlePut运行时对/api/myservice端点的n个PUT请求将导致handlePut路由的1次额外执行,该路由将在初始handlePut完成后执行,但我想要0次额外执行。

  @Override
  public void configure() {

    from("platform-http:/api/myservice?httpMethodRestrict=PUT")
      .routeId("myServiceRoute")
      .doTry()
        .process(exchange -> {
        SedaEndpoint sedaEndpoint = (SedaEndpoint)
        getContext().getEndpoint("seda:handlePut");
        int currentQueueSize = sedaEndpoint
          .getQueue()
          .size();
        if (currentQueueSize > 0) {
          throw new org.apache.camel.CamelExchangeException("Service busy", exchange);
        }
      })
        .wireTap("seda:handlePut")
        .setHeader("CamelHttpResponseCode", constant(204))
      .endDoTry()
      .doCatch(org.apache.camel.CamelExchangeException.class)
        .setHeader("CamelHttpResponseCode", constant(503))
        .setBody(constant("Service busy, please try again later"))
      .end();

    from("seda:handlePut?concurrentConsumers=1")
      .bean(myService, "slowMethod");
  }

这段代码使用 AtomicBoolean 的方式是应该完成的还是camel有更正确的方式吗?

java apache-camel
1个回答
0
投票

您可以检查飞行注册表,如果它> 1,则返回http服务器繁忙状态代码或其他内容。

© www.soinside.com 2019 - 2024. All rights reserved.