forked from trpc-group/trpc-cpp
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Feature: implement overload controller plugin token bucket trpc-group…
- Loading branch information
Showing
12 changed files
with
757 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,99 @@ | ||
licenses(["notice"]) | ||
|
||
package(default_visibility = ["//visibility:public"]) | ||
|
||
cc_library( | ||
name = "sliding_window_limiter_conf", | ||
srcs = ["sliding_window_limiter_conf.cc"], | ||
hdrs = ["sliding_window_limiter_conf.h"], | ||
defines = [] + | ||
select({ | ||
"//trpc:trpc_include_overload_control": ["TRPC_BUILD_INCLUDE_OVERLOAD_CONTROL"], | ||
"//conditions:default": [], | ||
}), | ||
visibility = [ | ||
"//visibility:public", | ||
], | ||
deps = [ | ||
"//trpc/log:trpc_log", | ||
"//trpc/overload_control:overload_control_defs", | ||
"@com_github_jbeder_yaml_cpp//:yaml-cpp", | ||
], | ||
) | ||
|
||
cc_test( | ||
name = "sliding_window_limiter_conf_test", | ||
srcs = ["sliding_window_limiter_conf_test.cc"], | ||
deps = [ | ||
":sliding_window_limiter_conf", | ||
"@com_google_googletest//:gtest_main", | ||
], | ||
) | ||
|
||
cc_library( | ||
name = "sliding_window_overload_controller", | ||
srcs = ["sliding_window_overload_controller.cc"], | ||
hdrs = ["sliding_window_overload_controller.h"], | ||
defines = [] + | ||
select({ | ||
"//trpc:trpc_include_overload_control": ["TRPC_BUILD_INCLUDE_OVERLOAD_CONTROL"], | ||
"//conditions:default": [], | ||
}), | ||
visibility = [ | ||
"//visibility:public", | ||
], | ||
deps = [ | ||
":sliding_window_limiter_conf", | ||
"//trpc/overload_control:overload_control_defs", | ||
"//trpc/overload_control:server_overload_controller", | ||
"//trpc/overload_control/flow_control:smooth_limiter", | ||
], | ||
) | ||
|
||
cc_test( | ||
name = "sliding_window_overload_controller_test", | ||
srcs = ["sliding_window_overload_controller_test.cc"], | ||
deps = [ | ||
":sliding_window_limiter_conf", | ||
":sliding_window_overload_controller", | ||
"//trpc/codec/testing:protocol_testing", | ||
"@com_google_googletest//:gtest", | ||
"@com_google_googletest//:gtest_main", | ||
], | ||
) | ||
|
||
cc_library( | ||
name = "sliding_window_limiter_server_filter", | ||
srcs = ["sliding_window_limiter_server_filter.cc"], | ||
hdrs = ["sliding_window_limiter_server_filter.h"], | ||
defines = [] + | ||
select({ | ||
"//trpc:trpc_include_overload_control": ["TRPC_BUILD_INCLUDE_OVERLOAD_CONTROL"], | ||
"//conditions:default": [], | ||
}), | ||
visibility = ["//visibility:public"], | ||
deps = [ | ||
":sliding_window_limiter_conf", | ||
":sliding_window_overload_controller", | ||
"//trpc/filter", | ||
"//trpc/log:trpc_log", | ||
"//trpc/overload_control:overload_control_defs", | ||
"//trpc/overload_control/common:report", | ||
"//trpc/server:server_context", | ||
"//trpc/server:service_impl", | ||
"//trpc/util:ref_ptr", | ||
], | ||
) | ||
|
||
cc_test( | ||
name = "sliding_window_limiter_server_filter_test", | ||
srcs = ["sliding_window_limiter_server_filter_test.cc"], | ||
data = ["sliding_window_overload_ctrl.yaml"], | ||
deps = [ | ||
":sliding_window_limiter_server_filter", | ||
"//trpc/codec/testing:protocol_testing", | ||
"//trpc/common/config:trpc_config", | ||
"//trpc/filter:filter_manager", | ||
"@com_google_googletest//:gtest_main", | ||
], | ||
) |
70 changes: 70 additions & 0 deletions
70
trpc/overload_control/sliding_window_limiter/sliding_window_limiter_conf.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,70 @@ | ||
/* | ||
* | ||
* Tencent is pleased to support the open source community by making | ||
* tRPC available. | ||
* | ||
* Copyright (C) 2024 THL A29 Limited, a Tencent company. | ||
* All rights reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
* | ||
*/ | ||
|
||
#ifdef TRPC_BUILD_INCLUDE_OVERLOAD_CONTROL | ||
|
||
#include "trpc/log/trpc_log.h" | ||
|
||
#include "trpc/overload_control/sliding_window_limiter/sliding_window_limiter_conf.h" | ||
|
||
namespace trpc::overload_control { | ||
|
||
void SlidingWindowLimiterControlConf::Display() const { | ||
TRPC_FMT_DEBUG("----------SlidingWindowLimiterControlConf---------------"); | ||
|
||
TRPC_FMT_DEBUG("limit: {}", limit); | ||
TRPC_FMT_DEBUG("window_size: {}", window_size); | ||
TRPC_FMT_DEBUG("is_report: {}", is_report); | ||
} | ||
} // namespace trpc::overload_control | ||
|
||
namespace YAML { | ||
|
||
YAML::Node convert<trpc::overload_control::SlidingWindowLimiterControlConf>::encode( | ||
const trpc::overload_control::SlidingWindowLimiterControlConf& config) { | ||
YAML::Node node; | ||
|
||
node["limit"] = config.limit; | ||
node["window_size"] = config.window_size; | ||
node["is_report"] = config.is_report; | ||
|
||
return node; | ||
} | ||
|
||
bool convert<trpc::overload_control::SlidingWindowLimiterControlConf>::decode( | ||
const YAML::Node& node, trpc::overload_control::SlidingWindowLimiterControlConf& config) { | ||
if (node["limit"]) { | ||
config.limit = node["limit"].as<int64_t>(); | ||
} | ||
if (node["window_size"]) { | ||
config.window_size = node["window_size"].as<int32_t>(); | ||
} | ||
if (node["is_report"]) { | ||
config.is_report = node["is_report"].as<bool>(); | ||
} | ||
|
||
return true; | ||
} | ||
|
||
} // namespace YAML | ||
|
||
#endif |
58 changes: 58 additions & 0 deletions
58
trpc/overload_control/sliding_window_limiter/sliding_window_limiter_conf.h
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,58 @@ | ||
/* | ||
* | ||
* Tencent is pleased to support the open source community by making | ||
* tRPC available. | ||
* | ||
* Copyright (C) 2024 THL A29 Limited, a Tencent company. | ||
* All rights reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
* | ||
*/ | ||
|
||
#ifdef TRPC_BUILD_INCLUDE_OVERLOAD_CONTROL | ||
|
||
#pragma once | ||
|
||
#include "yaml-cpp/yaml.h" | ||
|
||
#include "trpc/overload_control/overload_control_defs.h" | ||
|
||
namespace trpc::overload_control { | ||
|
||
/// @brief sliding_window concurrent control configuration. | ||
struct SlidingWindowLimiterControlConf { | ||
// Maximum number of requests per second. | ||
int64_t limit{1000}; | ||
// Window size | ||
int32_t window_size{100}; | ||
// Whether to report the judgment result to the monitoring plugin. | ||
bool is_report{false}; | ||
|
||
/// @brief Display the value of the configuration field. | ||
void Display() const; | ||
}; | ||
} // namespace trpc::overload_control | ||
|
||
namespace YAML { | ||
|
||
template <> | ||
struct convert<trpc::overload_control::SlidingWindowLimiterControlConf> { | ||
static YAML::Node encode(const trpc::overload_control::SlidingWindowLimiterControlConf& config); | ||
|
||
static bool decode(const YAML::Node& node, trpc::overload_control::SlidingWindowLimiterControlConf& config); | ||
}; | ||
|
||
} // namespace YAML | ||
|
||
#endif |
57 changes: 57 additions & 0 deletions
57
trpc/overload_control/sliding_window_limiter/sliding_window_limiter_conf_test.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/* | ||
* | ||
* Tencent is pleased to support the open source community by making | ||
* tRPC available. | ||
* | ||
* Copyright (C) 2024 THL A29 Limited, a Tencent company. | ||
* All rights reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
* | ||
*/ | ||
#ifdef TRPC_BUILD_INCLUDE_OVERLOAD_CONTROL | ||
|
||
#include "trpc/overload_control/sliding_window_limiter/sliding_window_limiter_conf.h" | ||
|
||
#include "gtest/gtest.h" | ||
|
||
namespace trpc::overload_control { | ||
namespace testing { | ||
|
||
TEST(SlidingWindowLimiterControlConf, All) { | ||
SlidingWindowLimiterControlConf conf; | ||
ASSERT_EQ(conf.limit, 1000); | ||
ASSERT_EQ(conf.window_size, 100); | ||
ASSERT_EQ(conf.is_report, false); | ||
|
||
YAML::convert<SlidingWindowLimiterControlConf> concurr_yaml; | ||
|
||
conf.limit = 20000; | ||
conf.window_size = 2000; | ||
|
||
YAML::Node concurr_node = concurr_yaml.encode(conf); | ||
|
||
SlidingWindowLimiterControlConf decode_conf; | ||
|
||
ASSERT_EQ(concurr_yaml.decode(concurr_node, decode_conf), true); | ||
|
||
ASSERT_EQ(decode_conf.limit, 20000); | ||
ASSERT_EQ(decode_conf.window_size, 2000); | ||
|
||
decode_conf.Display(); | ||
} | ||
|
||
} // namespace testing | ||
} // namespace trpc::overload_control | ||
|
||
#endif |
95 changes: 95 additions & 0 deletions
95
trpc/overload_control/sliding_window_limiter/sliding_window_limiter_server_filter.cc
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,95 @@ | ||
/* | ||
* | ||
* Tencent is pleased to support the open source community by making | ||
* tRPC available. | ||
* | ||
* Copyright (C) 2024 THL A29 Limited, a Tencent company. | ||
* All rights reserved. | ||
* | ||
* Licensed under the Apache License, Version 2.0 (the "License"); | ||
* you may not use this file except in compliance with the License. | ||
* You may obtain a copy of the License at | ||
* | ||
* http://www.apache.org/licenses/LICENSE-2.0 | ||
* | ||
* Unless required by applicable law or agreed to in writing, software | ||
* distributed under the License is distributed on an "AS IS" BASIS, | ||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||
* See the License for the specific language governing permissions and | ||
* limitations under the License. | ||
* | ||
*/ | ||
|
||
#ifdef TRPC_BUILD_INCLUDE_OVERLOAD_CONTROL | ||
|
||
#include "trpc/overload_control/sliding_window_limiter/sliding_window_limiter_server_filter.h" | ||
|
||
#include "trpc/common/config/trpc_config.h" | ||
#include "trpc/log/trpc_log.h" | ||
#include "trpc/overload_control/common/report.h" | ||
|
||
namespace trpc::overload_control { | ||
|
||
int SlidingWindowLimiterServerFilter::Init() { | ||
bool ok = TrpcConfig::GetInstance()->GetPluginConfig<SlidingWindowLimiterControlConf>( | ||
kOverloadCtrConfField, kSlidingWindowLimiterName, sliding_window_conf_); | ||
if (!ok) { | ||
TRPC_FMT_DEBUG("SlidingWindowLimiterServerFilter read config failed, will use a default config"); | ||
} | ||
sliding_window_conf_.Display(); | ||
|
||
service_controller_ = std::make_unique<SlidingWindowOverloadController>( | ||
sliding_window_conf_.limit, sliding_window_conf_.window_size, sliding_window_conf_.is_report); | ||
|
||
return 0; | ||
} | ||
|
||
std::vector<FilterPoint> SlidingWindowLimiterServerFilter::GetFilterPoint() { | ||
return { | ||
FilterPoint::SERVER_PRE_SCHED_RECV_MSG, | ||
// This tracking point is not used, but tracking points must be paired, so it is added here. | ||
FilterPoint::SERVER_POST_SCHED_RECV_MSG, | ||
}; | ||
} | ||
|
||
void SlidingWindowLimiterServerFilter::operator()(FilterStatus& status, FilterPoint point, | ||
const ServerContextPtr& context) { | ||
switch (point) { | ||
case FilterPoint::SERVER_PRE_SCHED_RECV_MSG: { | ||
OnRequest(status, context); | ||
break; | ||
} | ||
default: { | ||
break; | ||
} | ||
} | ||
} | ||
|
||
void SlidingWindowLimiterServerFilter::OnRequest(FilterStatus& status, const ServerContextPtr& context) { | ||
if (TRPC_UNLIKELY(!context->GetStatus().OK())) { | ||
// If it is already a dirty request, it will not be processed further to ensure that the first error code is | ||
// not overwritten. | ||
return; | ||
} | ||
|
||
bool passed = service_controller_->BeforeSchedule(context); | ||
if (!passed) { | ||
context->SetStatus( | ||
Status(TrpcRetCode::TRPC_SERVER_OVERLOAD_ERR, 0, "rejected by server token bucket limiter overload control")); | ||
status = FilterStatus::REJECT; | ||
} | ||
|
||
// Report the result. | ||
if (sliding_window_conf_.is_report) { | ||
OverloadInfo infos; | ||
infos.attr_name = kOverloadctrlSlidingWindowLimiter; | ||
infos.report_name = fmt::format("/{}/{}", context->GetCalleeName(), context->GetFuncName()); | ||
infos.tags[kOverloadctrlPass] = (passed == true ? 1 : 0); | ||
infos.tags[kOverloadctrlLimited] = (passed == false ? 1 : 0); | ||
Report::GetInstance()->ReportOverloadInfo(infos); | ||
} | ||
} | ||
|
||
} // namespace trpc::overload_control | ||
|
||
#endif |
Oops, something went wrong.