Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

【腾讯犀牛鸟计划】实现过载保护插件 - 滑动时间窗口 #144 #179

Merged
merged 46 commits into from
Sep 18, 2024

Conversation

2549141519
Copy link
Contributor

https://docs.qq.com/doc/DWHZPbXFNc0drZUtE 里边有实现思路和编译运行命令。
个人仓库链接为https://github.com/2549141519/trpc-cpp 代码在main分支下

我pr的分支 仅仅添加了新文件夹smooth_filter 除此之外别无改动 如果想测试example 和单元测试 请去main分支 具体步骤写在了文档里

如果有任何问题 请你告诉我 我将及时改动 谢谢您的review

/// @var: Default number of time frames per second
constexpr int32_t kDefaultNum = 100;

class SmoothLimit : public ServerOverloadController
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

你这里可以直接用 trpc/overload_control/flow_control/smooth_limiter.h 吗?

框架已经实现了滑动窗口和固定窗口算法,都在flow_control文件夹里,你可以把他们与ServerOverloadController做一下集成吗?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

谢谢您的回复! 我已经作出改动

private:
std::string name_;

SmoothLimiter smooth_limit_;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

可以将这个变量定义为一个智能指针,在Destroy里销毁,线程资源停止及销毁动作不太适合放在析构函数里。

/// @brief Default number of time frames per second
static const int32_t kDefaultNumber = 100;

class SmoothLimit : public ServerOverloadController
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

类名可以改成 SmoothLimitOverloadController

namespace trpc::overload_control {

/// @brief The configuration of interface-level flow control
struct Server_FuncLimiterConfig {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

看到 flow_controller_conf、flow_controller_factory等的实现,基本是把 trpc/overload_control/flow_control 里文件内容给拷贝过来了;

这块代码不应该被重复拷贝,而是应该复用(使用函数、使用类);

具体到过载保护来说,你需要在filter里调用OverloadController

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

1 .类名字我已修改
2. 封装smooth_filter地方我采用了智能指针 destroy的时候是否是调用reset我不太确定
3. conf文件我复用了flow_control的,并且运行结果没问题
4. generator文件不太好复用,里边其实是注册smooth_filter,这个地方的smooth_filter和原始的flow_control的多了一个变量,导致不能直接复用,只有两个func我感觉可以自己写

@weimch
Copy link
Contributor

weimch commented Sep 10, 2024

调整时候有遇到啥困难或者不确定的吗?

Copy link

github-actions bot commented Sep 10, 2024

CLA Assistant Lite bot All contributors have signed the CLA ✍️ ✅


/// @brief Register the flow controller object for the service.
/// @param flow_conf Flow control conf.
void Server_RegisterFlowController(const FlowControlLimiterConf& flow_conf);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

方法名全驼峰式命名,你可以换一个名字

class Server_FlowControlServerFilter : public MessageServerFilter {
public:
/// @brief Name of filter
std::string Name() override { return "my_flow_control"; }
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

插件名定义成有意义的常量

namespace trpc::overload_control {

bool SmoothLimitOverloadController::Init() {
// nothing to do,The time thread automatically starts.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

你的Controller类,可以在Init的时候,创建并管理一组SmoothLimit的map吧,只需要复用CreateFlowController就好了吧,也不用你自己实现一个xx_generator

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

在BeforeSchedule里,从这组SmoothLimit里取出对应配置的限流器,调用一下就好了吧

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

老师好,这块我没看懂,有两个问题:
1.CreateFlowController里面调用了限流器的构造函数,现在我自己实现的限流器变成了xxx_controller,那么这里也需要修改吧?怎么直接复用CreateFlowController呢?
5f7a6b501042b37c281595bc6d15748
2.现在要求不实现xx_generator,在controller中创建并管理一组map,是要在xxx_filter中加载配置文件,并把配置文件作为参数传入controller的构造函数?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

创建并管理一组FlowController


bool SmoothLimitOverloadController::Init() {
// nothing to do,The time thread automatically starts.
return true;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

另外,文件名和类名应该更有意义,你可以想一下怎么改类名和文件名比较好

namespace trpc::overload_control {

bool SmoothLimitOverloadController::Init() {
std::vector<FlowControlLimiterConf> flow_control_confs;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

注意缩进,可以用clang-format工具格式化一遍提交的代码,格式化使用trpc-cpp下的.clang-format配置

ip: 0.0.0.0 # Service bind ip
port: 12345
filter:
- my_flow_control # Service bind port
Copy link
Contributor

@weimch weimch Sep 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

my_flow_control换成有意义的插件名

}

bool SmoothLimitOverloadController::BeforeSchedule(const ServerContextPtr& context) {
auto service_controller = SmoothLimitOverloadController::GetInstance()->GetFlowController(context->GetCalleeName());
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

不需要使用单例,直接从map里获取就好了

for (const auto& func_conf : flow_conf.func_limiters) {
if (!func_conf.limiter.empty()) {
std::string service_func_name = fmt::format("/{}/{}", flow_conf.service_name, func_conf.name);
FlowControllerPtr func_controller =
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这里是只创建了smooth滑动窗口限流器吗?defualt固定窗口限流器有创建吗?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

defalut会创建固定窗口 这个地方直接调用的flow_control的conf读取yaml配置 generator创建,map的value类型是父类 可以的

//
//

#ifdef TRPC_BUILD_INCLUDE_OVERLOAD_CONTROL
Copy link
Contributor

@weimch weimch Sep 11, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

补充下单测,在docs/zh文档里补充下用法

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

老师 我已经作出修改

  1. clang-format工具格式化
  2. my_flow_control替换成server_flow_control
  3. 直接从map里获取
  4. 补充下单测,在docs/zh文档里补充用法

plugins:
prometheus:

window_limit_overload_control:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

为啥不能是这样的配置?

plugins:
  overload_control:
      window_limiter:
        - xxxxx


服务端流量控制配置如下(详细配置参考:[flow_test.yaml](../../trpc/overload_control/flow_control/flow_test.yaml)):
```
global:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

除了插件之外,其他的无关配置都删掉


namespace trpc::overload_control {

constexpr char WindowLimitOverloadControlFilterName[] = "window_limiter";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

类型/变量名都换成WindowLimiter吧,名词更好


namespace trpc::overload_control {

constexpr char WindowLimitOverloadControlFilterName[] = "window_limiter";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

常量名需要加上 kWindowxxxx


namespace trpc::overload_control {

constexpr char WindowLimitOverloadControllerName[] = "WindowLimitOverloadController";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

kWindowLimiterOverloadControllerName

constexpr char kWindowLimitControlName[] = "window_limiter";

/// @brief Default number of time frames per second
constexpr int32_t kDefaultNumber = 100;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个没有被使用吧?是不是可以删掉


void RegisterLimiter(const std::string& name, FlowControllerPtr limiter);

FlowControllerPtr GetLimiter(const std::string& name);
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

这个方法不需要定义成public的吧


constexpr char kWindowLimitOverloadCtrConfField[] = "window_limit_overload_control";

constexpr char kWindowLimitControlName[] = "window_limiter";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

限流器名字定义在这里:trpc/overload_control/overload_control_defs.h

- func_limiter:指定服务名 `service_name` 下的接口级流控策略;每个服务可以存在多个接口,每个接口可以选择不同的流量控制算法,介绍如下:
- `name`:接口名称,如:`SayHello` 和 `Route`
- `limiter`:指定接口流控算法,例如:`Route` 配置了滑动窗口(smooth)算法,最大 QPS 是 80000
- is_report:是否上报监控数据到监控插件,**注意,该配置必须与监控插件一起使用(例如配置:plugins->metrics->prometheus,则会上报到 prometheus 上),如果没有配置监控插件,该选项无意义**,不同流量控制算法监控数据分别如下:
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

默认设置成不上报

Copy link
Contributor

@helloopenworld helloopenworld left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

approve

Copy link
Contributor

@helloopenworld helloopenworld left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

approve

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants