Throttler – restricting the number of messages flowing to an endpoint

When you need to limit the number of messages flowing through a route during a specified time period, the Throttler EIP can help. For example, if you have a downstream system that can only handle 10 requests per second, using a Throttler EIP within your route can ensure that you do not exceed that rate.

This recipe will show you how to restrict the number of messages routed to a set of endpoints during a specified time period.

Getting ready

The Java code for this recipe is located in the org.camelcookbook.routing.throttler package. The Spring XML files are located under src/main/resources/META-INF/spring and prefixed with throttler.

How to do it...

In order to use the Throttler, perform the following steps:

  1. You must specify the maximum number of messages to be allowed per time period (defaults to 1,000 ms).

    In the XML DSL, this is specified as an Expression to allow for the maximum rate to be changed at runtime. In this example, we are using the Constant Expression Language to set the maximum number of messages to 5.

    <route>
      <from uri="direct:start"/>
      <throttle>
        <constant>5</constant>
        <to uri="mock:throttled"/>
      </throttle>
    </route>

    In the Java DSL, you can provide either java.lang.Long, which will be interpreted like the results of a Constant Expression Language expression, or you can provide an Expression that will be evaluated for each message to determine the current maximum number of messages per time period.

    Note

    You need to specify .end() statement after the steps you want constrained by the Throttler if you have additional steps afterwards.

    from("direct:start")
      .throttle(5)
        .to("mock:throttled")
      .end()
      .to("mock:after");
  2. Optionally, explicitly specify the time period over which throttling is performed in your route. This is the time period for which the Throttler will only allow the maximum number of messages you specified in the previous step. This example sets the time period to 2,000 ms or 2 seconds, so every 2 seconds the Throttler will allow up to 5 messages to be processed.

    In the XML DSL, this is written as:

    <route>
      <from uri="direct:start"/>
      <throttle timePeriodMillis="2000">
        <constant>5</constant>
        <to uri="mock:throttled"/>
      </throttle>
    </route>

    In the Java DSL, the same route is expressed as:

    from("direct:start")
      .throttle(5).timePeriodMillis(2000)
        .to("mock:throttled")
      .end()
      .to("mock:after");

How it works...

The Throttler evaluates the maximumRequestsPerPeriod Expression for each message being processed. The processing of this message is delayed if it exceeds the specified rate. The use of an Expression allows for the throttling rate to be changed at runtime through aspects of the current message, or calls to an external Java object (using the Bean Expression Language). By default, the Throttler will block the route's thread of execution until the throttle rate drops below the specified maximum.

An example of using a message header, ThrottleRate, to set the throttle rate is as follows. In this example, the header name can be anything, you just need to provide the name of the header whose value will be evaluated as java.lang.Long and used as the maximumRequestsPerPeriod.

<throttle timePeriodMillis="10000">
  <header>ThrottleRate</header>
  <to uri="mock:throttled"/>
</throttle>

There's more...

The Throttler provides an asyncDelayed option that will take messages that would exceed the throttle rate, and schedule future execution for them, releasing the route's current thread for other uses. An alternative thread pool can be provided through the executorServiceRef option. Here's an example in the XML DSL:

<camelContext xmlns="http://camel.apache.org/schema/spring">
  <threadPoolProfile id="myThrottler"
                     poolSize="5"
                     maxPoolSize="20"
                     maxQueueSize="1000"
                     rejectedPolicy="CallerRuns"/>

  <route>
    <from uri="direct:start"/>
    <to uri="mock:unthrottled"/>
    <throttle timePeriodMillis="10000"
              asyncDelayed="true"
              executorServiceRef="myThrottler">
      <constant>5</constant>
      <to uri="mock:throttled"/>
    </throttle>
    <to uri="mock:after"/>
  </route>
</camelContext>

If your needs are less exacting, you can use org.apache.camel.impl.ThrottlingInflightRoutePolicy class instead of the Throttler. The ThrottlingInflightRoutePolicy is less accurate than the Throttler, but can be more easily applied to one or more routes within a Camel context.

..................Content has been hidden....................

You can't read the all page of ebook, please click here login for view all page.
Reset
18.216.42.251