Skip to content

Commit b301f77

Browse files
authored
Docs: Add overload control for flow control (#42)
1 parent cb548ae commit b301f77

18 files changed

Lines changed: 369 additions & 14 deletions

docs/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,8 @@ English | [中文](README.zh_CN.md)
4444
* [custom filter](./en/filter.md)
4545
* Flow-Control & Overload-Protect
4646
* [concurrency requests limiter plugin](./en/overload_control_concurrency_limiter.md)
47-
* [concurrency fibers limiter plugin](./en/overload_control_filter_limiter.md)
47+
* [concurrency fibers limiter plugin](./en/overload_control_fiber_limiter.md)
48+
* [flow control limiter plugin](./en/overload_control_flow_limiter.md)
4849
* Naming
4950
* [custom naming plugin](./en/custom_naming.md)
5051
* [mesh-polaris](https://github.com/trpc-ecosystem/cpp-naming-polarismesh/blob/main/README.md)

docs/README.zh_CN.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,8 @@
4343
* [开发自定义拦截器](./zh/filter.md)
4444
* 流控和过载保护
4545
* [基于并发请求的过载保护插件](./zh/overload_control_concurrency_limiter.md)
46-
* [基于并发 Fiber 个数的过载保护插件](./zh/overload_control_filter_limiter.md)
46+
* [基于并发 Fiber 个数的过载保护插件](./zh/overload_control_fiber_limiter.md)
47+
* [基于流量控制的过载保护插件](./zh/overload_control_flow_limiter.md)
4748
* Naming插件
4849
* [开发自定义naming插件](./zh/custom_naming.md)
4950
* [mesh-polaris](https://github.com/trpc-ecosystem/cpp-naming-polarismesh/blob/main/README.zh_CN.md)

docs/en/overload_control_filter_limiter.md renamed to docs/en/overload_control_fiber_limiter.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
[中文](../zh/overload_control_filter_limiter.md)
1+
[中文](../zh/overload_control_fiber_limiter.md)
22

33
# Overview
44

Lines changed: 172 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,172 @@
1+
[中文](../zh/overload_control_flow_limiter.md)
2+
3+
# Overview
4+
5+
The capacity of a single node to handle requests is limited. In order to ensure high availability of the service, we must impose some restrictions on the number of requests. The need for flow control arises in this context. The current tRPC-Cpp framework supports flow control configuration at two levels: service and function. The measurement dimension is QPS.
6+
7+
- Two flow control algorithms are used:
8+
- Fixed window (counting method), corresponding to the flow control controller: `seconds` (fixed window), also known as `default`.
9+
- Sliding window, corresponding to the flow control controller: `smooth` (sliding window).
10+
- Throttling trigger conditions
11+
12+
First, the service flow limit is checked. If the service flow limit is exceeded, a flow control error is returned. Then, the interface flow limit is checked. If it exceeds the limit, a flow control error is returned.
13+
14+
*Note: The algorithm principles behind flow control are quite complex. A dedicated section will be provided to explain them in detail.*
15+
16+
# Principle
17+
18+
## Principle diagram of overload protection based on flow control
19+
20+
![flow_control_limiter](../images/flow_control_limiter.png)
21+
The core point in the diagram is the `FlowControlLimiter`, which is primarily responsible for calculating the current QPS (requests per second) using traffic control algorithms. It compares the number of requests (`reqs_counter`) within a 1-second time window to the maximum number of requests configured in the window (`win_limit`) to determine whether to reject the new incoming request (`curr_req`). The logic is straightforward.
22+
23+
## Implementation code
24+
25+
The overload protection implementation of the framework is based on [filters](./filter.md), in order to ensure flow control protection as early as possible. This filter is placed before the request is enqueued, and the specific implementation of the filter placement is as follows:
26+
27+
```cpp
28+
std::vector<FilterPoint> FlowControlServerFilter::GetFilterPoint() {
29+
return {
30+
FilterPoint::SERVER_PRE_SCHED_RECV_MSG,
31+
// ...
32+
};
33+
}
34+
```
35+
36+
Source code: [flow_control_server_filter](../../trpc/overload_control/flow_control/flow_controller_server_filter.cc)
37+
38+
# Usage example
39+
40+
The overload protection filter based on flow control can currently **only be applied to the server-side, and client-side support is not available at the moment**. Users can use it without modifying any code by simply enabling compilation and adding configurations, making it very convenient.
41+
42+
## Compilation options
43+
44+
Add the following line to the `.bazelrc` file.
45+
46+
```sh
47+
build --define trpc_include_overload_control=true
48+
```
49+
50+
## Configuration file
51+
52+
The server-side flow control configuration is as follows (for detailed configuration, refer to [flow_test.yaml](../../trpc/overload_control/flow_control/flow_test.yaml)):
53+
54+
```yaml
55+
#Server configuration
56+
server:
57+
app: test #Business name, such as: COS, CDB.
58+
server: helloworld #Module name of the business
59+
admin_port: 21111 # Admin port
60+
admin_ip: 0.0.0.0 # Admin ip
61+
service: #Business service, can have multiple.
62+
- name: trpc.test.helloworld.Greeter #Service name, needs to be filled in according to the format, the first field is default to trpc, the second and third fields are the app and server configurations above, and the fourth field is the user-defined service_name.
63+
network: tcp #Network listening type: for example: TCP, UDP.
64+
ip: 0.0.0.0 #Listen ip
65+
port: 10001 #Listen port
66+
protocol: trpc #Service application layer protocol, for example: trpc, http.
67+
accept_thread_num: 1 #Number of threads for binding ports.
68+
filter:
69+
- flow_control
70+
71+
#Plugin configuration.
72+
plugins:
73+
# metrics:
74+
# prometheus:
75+
# ...
76+
overload_control:
77+
flow_control:
78+
- service_name: trpc.test.helloworld.Greeter #service name.
79+
is_report: true # Whether to report monitoring data.
80+
service_limiter: default(100000) # Service-level flow control limiter, standard format: name (maximum limit per second), empty for no limit.
81+
func_limiter: #Interface-level flow control.
82+
- name: SayHello ##Method name
83+
limiter: seconds(50000) #Interface-level flow control limiter, standard format: name (maximum limit per second), empty for no limit.
84+
- name: Route #Method name
85+
limiter: smooth(80000) #Interface-level flow control limiter, standard format: name (maximum limit per second), empty for no limit.
86+
```
87+
88+
The key points of the configuration are as follows:
89+
90+
- flow_control: The name of the flow control overload protector
91+
- service_name: The name of the service associated with flow control.
92+
- service_limiter: Specifies the service-level flow control algorithm for the service name `service_name`. Here, the configuration `default(100000)` is explained as follows:
93+
- `default` (equivalent to `seconds`): Indicates that the fixed window flow control algorithm is selected.
94+
- `100000`: Represents the maximum number of requests per second, i.e., the maximum QPS is 100000.
95+
- func_limiter: Specifies the interface-level flow control strategy for the service name `service_name`. Each service can have multiple interfaces, and each interface can choose a different flow control algorithm. The details are as follows:
96+
- `name`: The name of the interface, such as `SayHello` and `Route`.
97+
- `limiter`: Specifies the flow control algorithm for the interface. For example, `Route` is configured with the sliding window (smooth) algorithm, with a maximum QPS of 80000.
98+
- is_report: Specifies whether to report monitoring data to the monitoring plugin. **Note that this configuration must be used together with a monitoring plugin (e.g., configuration: plugins->metrics->prometheus), otherwise, this option is meaningless**. The monitoring data for different flow control algorithms is as follows:
99+
- seconds:
100+
- `SecondsLimiter`: The name of the flow control algorithm used to check if the configuration matches the one executed in the program.
101+
- `/{callee_name}/{method}`: The format of the monitoring name, composed of the callee service (callee_name) and the method name (method). For example: `/trpc.test.helloworld.Greeter/SayHello`.
102+
- `current_qps`: The current concurrent QPS value.
103+
- `max_qps`: The configured maximum QPS, used to check if the maximum QPS in the configuration matches the one executed in the program.
104+
- `window_size`: The number of sampling windows. Users may not need to pay attention to this.
105+
- `Pass`: The pass status of a single request, where 0 means intercepted and 1 means passed.
106+
- `Limited`: The interception status of a single request, where 1 means intercepted and 0 means passed. This is the opposite of the `Pass` monitoring attribute mentioned above.
107+
- smooth:
108+
- `SmoothLimiter`: The name of the flow control algorithm used to check if the configuration matches the one executed in the program.
109+
- `/{callee_name}/{method}`: The format of the monitoring name, composed of the callee service (callee_name) and the method name (method). For example: `/trpc.test.helloworld.Greeter/SayHello`.
110+
- `active_sum`: The sum of all requests in the hit time slots, representing the QPS value at the moment after excluding the current request. If it exceeds the maximum QPS, the `hit_num` below will be 0.
111+
- `hit_num`: The QPS value after adding one request to the hit time slot.
112+
- `max_qps`: The configured maximum QPS, used to check if the maximum QPS in the configuration matches the one executed in the program.
113+
- `window_size`: The number of sampling windows. Users may not need to pay attention to this.
114+
- `Pass`: The pass status of a single request, where 0 means intercepted and 1 means passed.
115+
- `Limited`: The interception status of a single request, where 1 means intercepted and 0 means passed. This is the opposite of the `Pass` monitoring attribute mentioned above.
116+
117+
## Implementing flow control using code
118+
119+
In addition to configuring flow control, flow control functionality can also be implemented directly through code (note the difference between service-level and interface-level flow control code). The registration methods for service-level and interface-level flow controllers for business users are as follows:
120+
121+
```cpp
122+
class HelloWorldServer : public ::trpc::TrpcApp {
123+
public:
124+
// ...
125+
int RegisterPlugins() {
126+
127+
// ...
128+
129+
// Registering a service-level flow controller.
130+
trpc::FlowControllerPtr service_controller(new trpc::SmoothLimter(200000, true, 100));
131+
trpc::FlowControllerFactory::GetInstance()->Register( "trpc.test.helloworld.Greeter", service_controller);
132+
133+
// Registering an interface-level flow controller.
134+
trpc::FlowControllerPtr say_hello_controller(new trpc::SecondsLimiter(10000, true, 100));
135+
trpc::FlowControllerFactory::GetInstance()->Register( "/trpc.test.helloworld.Greeter/SayHello", say_hello_controller);
136+
return 0;
137+
}
138+
139+
};
140+
```
141+
142+
The registration logic for the flow controller must be executed in the `RegisterPlugins` function within the `trpc::TrpcApp` interface.
143+
144+
- For detailed information about the `trpc::SmoothLimiter` class, refer to: [SmoothLimiter](../../trpc/overload_control/flow_control/smooth_limiter.h).
145+
- For detailed information about the `trpc::SecondsLimiter` class, refer to: [SecondsLimiter](../../trpc/overload_control/flow_control/seconds_limiter.h).
146+
147+
# Principles of flow control algorithms
148+
149+
Below is a brief explanation of the implementation algorithms for fixed window traffic control and sliding window traffic control.
150+
151+
## Fixed window traffic control algorithm
152+
153+
The fixed window algorithm, also known as the fixed window counter algorithm, divides time into fixed-sized windows along the timeline. It limits the maximum number of requests allowed within each time window to a predefined threshold. At any given moment, the system operates within a specific time window. When a new request arrives within the current time window, the counter for that window is atomically incremented. Additionally, each new request checks the total number of requests allowed within the current time window against the threshold. If the counter exceeds the threshold, the remaining requests are rejected. It is important to note that as time progresses and the time window shifts, the counter within each window is reset to 0.
154+
155+
![flow_control_limiter_second_1](../images/flow_control_limiter_second_1.png)
156+
157+
The fixed window algorithm is the simplest traffic control algorithm in terms of principles and implementation. It typically involves setting a global counter to track the number of requests allowed within the current time window and making decisions for incoming requests. Additionally, the counter is reset whenever the time reaches the start of a new time window. The specific steps are as follows:
158+
159+
- Divide time into multiple windows.
160+
- Increment the counter for each request within the window.
161+
- If the counter exceeds the limit, reject the remaining requests within the current time window. Reset the counter when the time reaches the next window. ![flow_control_limiter_second_2](../images/flow_control_limiter_second_2.png) However, the fixed window algorithm also has a **boundary problem** due to the fixed position of the windows. This means that there can be situations where the actual number of requests passing through exceeds the limit at the boundary positions of the windows. While the number of requests allowed within each individual time window is below the threshold, the combination of two windows at the boundary position may result in a window size that still satisfies the 1-second setting, but allows twice the number of requests as the threshold.
162+
163+
## Sliding window traffic control algorithm
164+
165+
To address the limitations of the fixed window algorithm described above, researchers have developed the sliding window counter algorithm. Instead of using fixed windows, this algorithm uses **sliding** windows that move with time. This ensures that within each sliding window, the condition `counter <= limit` is always satisfied. The sliding windows overlap with each other due to the sliding algorithm, eliminating the occurrence of boundary effects. The specific steps of the sliding window algorithm are as follows:
166+
167+
- Divide time into multiple intervals.
168+
- Within each time interval, divide time into smaller slices. The sliding window moves one slice at a time according to the time rules.
169+
- Increment the counter for each request within each window.
170+
- Check the total count within the latest sliding window against the threshold to decide whether to accept or reject the service. Services that exceed the threshold are rejected.
171+
- When the sliding window moves, the counts from the slices that move out of the sliding window are discarded, and the counts within the new slices are reset to zero.
172+
![flow_control_limiter_smooth](../images/flow_control_limiter_smooth.png) The sliding window algorithm is an upgraded version of the fixed window algorithm. By subdividing the windows and **sliding** them according to time, it improves accuracy and eliminates **boundary effects**. However, this improvement comes at the cost of increased computational overhead.

docs/en/plugin_management.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,8 @@ The framework takes inspiration from Java's Aspect-Oriented Programming (AOP) pa
5656

5757
It provides the ability for flow controlling and overload protecting. For more details, please refer to the **documentation of customizing Flow-Control & Overload-Protect plugin**.
5858
* [Concurrent requests limiter](./overload_control_concurrency_limiter.md)
59-
* [Concurrent fibers limiter](./overload_control_filter_limiter.md)
59+
* [Concurrent fibers limiter](./overload_control_fiber_limiter.md)
60+
* [Flow control limiter plugin](./overload_control_flow_limiter.md)
6061

6162
## Other features
6263

docs/en/server_guide.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -240,4 +240,5 @@ See [Transparent proxy](transparent_service.md).
240240
### Flow-Control & Overload-Protect
241241

242242
* See [Concurrent requests limiter](./overload_control_concurrency_limiter.md)
243-
* See [Concurrent fibers limiter](./overload_control_filter_limiter.md)
243+
* See [Concurrent fibers limiter](./overload_control_fiber_limiter.md)
244+
* See [Flow control limiter plugin](./overload_control_flow_limiter.md)
95.9 KB
Loading
226 KB
Loading
223 KB
Loading
297 KB
Loading

0 commit comments

Comments
 (0)