Flow Control
Introduction
Based on the real-time statistics collected in Sentinel, FlowSlot will use pre-set rules to decide whether the incoming requests should be controlled.
One resource can have multiple flow control rules. The FlowSlot
will traverse these rules until one of them is triggered or all rules have been passed.
A flow control rule mainly consists of the following items, and you can use a combination of different items to satisfy different flow control needs.
resource
:resource namecount
: the thresholdgrade
: metric type (QPS or concurrency)strategy
: select flow control strategy based on invocation relation (invocation chain)controlBehavior
: effect of traffic shaping
Flow Control by Thread/QPS
Metric Type
You can control either by QPS and concurrency. It is defined by the grade
field in FlowRule
. Both concurrent thread count and request count are collected at runtime.
Concurrency
This mode is usually used to prevent thread pools from being occupied. If an invocation takes a long time to finish, threads blocked on the invocation will be congested. The longer the response takes, the more threads might be occupied.
Besides concurrency (aka. semaphore isolation), there are other ways to achieve this: thread pool isolation.
- Thread pool isolation: Allocate managed thread pools to handle different invocations. When there are no more idle threads in the pool, the request is rejected without affecting other resources. When an invocation exceeds the timeout, the invocation will be cut down.
- Semaphore isolation: Limit the concurrency count of the invocation.
The benefit of using thread pools is that you can isolate business logic completely by pre-allocating thread pools. But it also brings us extra costs of context switch and additional threads. If the incoming request is already handled in a separate thread, for instance, a servlet request, it will almost double the thread overhead if using the thread pool mode.
So we recommend using concurrent thread count flow control, which represents lightweight semaphore isolation.
QPS
When QPS exceeds the threshold, we will take actions to control the incoming requests, and this can be done by configuring the controlBehavior
field in FlowRule
.
1. Immediately reject (RuleConstant.CONTROL_BEHAVIOR_DEFAULT
)
This is the default behavior. The exceeded requests are rejected immediately and the FlowException is thrown.
2. WarmUp(RuleConstant.CONTROL_BEHAVIOR_WARM_UP
)
If the usage of the system has been low for a while, but all of a sudden a large amount of requests comes in, the system might not be able to handle all these requests at once. However, if we steadily increase the incoming requests and allows the system to warm up, it may be able to handle all the requests eventually.
This warm-up period can be configured by setting the warmUpPeriodSec
field in FlowRule
.
3.Rate limiter (RuleConstant.CONTROL_BEHAVIOR_RATE_LIMITER
)
This strategy strictly controls the interval between requests. In other words, it allows requests to pass at a uniform rate.
This strategy is an implementation of leaky bucket. It is used to handle requests at a stable rate and is often used to process burst requests instead of rejecting them. For instance, a sudden inflow of messages. When a large number of requests arrive at the same time, the system can handle all these incoming requests at a fixed rate.
Flow Control by Call Path
We use the NodeSelectorSlot
to establish the invocation chain of resources, and the ClusterBuilderSlot
to collect the caller's runtime statistic data.
By caller
When calling ContextUtil.enter(resourceName, origin)
, the parameter origin
indicates the identity of the caller (e.g. service name of peer side). The ClusterBuilderSlot
will collect this info, and use it to perform flow control.
This information can be displayed by the following command:
id: nodeA
idx origin threadNum passedQps blockedQps totalQps aRt 1m-passed 1m-blocked 1m-total
1 caller1 0 0 0 0 0 0 0 0
2 caller2 0 0 0 0 0 0 0 0
The origin
can be defined by the field limitApp
in FlowRule. This field has the following values:
default
: No specific caller. If the total value of this resource exceeds the threshold defined in this rule, the incoming request will be blocked.<<origin>>
: A specific caller has exceeded the threshold defined in the rule.other
: This rule applies to requests from a caller that is not defined explicitly in theorigin
field for this resource.
By entrance
The path is maintained in NodeSelectorSlot
. For example, the resource nodes can come from either entrance1 or entrance2.
machine-root
/ \
/ \
Entrance1 Entrance2
/ \
/ \
DefaultNode(nodeA) DefaultNode(nodeA)
We can shape the flow by setting the field strategy
to RuleConstant.CHAIN
, and ref_identity
to a specified entrance.
By related resource
For instance, two resources will access the same database record. ResourceA will read records from the database, resourceB will write records to the database. The frequency of ResourceA accessing the database depends on ResourceB. We can achieve this by configuring a rule for ResourceA with the value of the strategy
field as RuleConstant.RELATE
, and the value of ref_identity
as ResourceB.