mirror of
https://github.com/alibaba/higress.git
synced 2026-04-24 13:37:27 +08:00
Update extensions & release 1.0.0-rc (#281)
This commit is contained in:
@@ -1,3 +1,17 @@
|
||||
# Copyright (c) 2022 Alibaba Group Holding Ltd.
|
||||
#
|
||||
# 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.
|
||||
|
||||
load("@proxy_wasm_cpp_sdk//bazel/wasm:wasm.bzl", "wasm_cc_binary")
|
||||
load("//bazel:wasm.bzl", "declare_wasm_image_targets")
|
||||
|
||||
@@ -13,9 +27,9 @@ wasm_cc_binary(
|
||||
"@com_google_absl//absl/strings",
|
||||
"@com_google_absl//absl/time",
|
||||
"//common:json_util",
|
||||
"@proxy_wasm_cpp_sdk//:proxy_wasm_intrinsics",
|
||||
"//common:http_util",
|
||||
"//common:rule_util",
|
||||
"@proxy_wasm_cpp_sdk//:proxy_wasm_intrinsics",
|
||||
],
|
||||
)
|
||||
|
||||
@@ -34,8 +48,8 @@ cc_library(
|
||||
"@com_google_absl//absl/strings",
|
||||
"//common:json_util",
|
||||
"@proxy_wasm_cpp_host//:lib",
|
||||
"//common:http_util",
|
||||
"//common:rule_util",
|
||||
"//common:http_util_nullvm",
|
||||
"//common:rule_util_nullvm",
|
||||
],
|
||||
)
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include <unordered_map>
|
||||
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "absl/strings/str_format.h"
|
||||
#include "absl/strings/str_join.h"
|
||||
|
||||
namespace {
|
||||
@@ -40,11 +41,16 @@ bool getToken(int rule_id, const std::string &key) {
|
||||
for (int i = 0; i < maxGetTokenRetry; i++) {
|
||||
if (WasmResult::Ok !=
|
||||
getSharedData(tokenBucketKey, &token_bucket_data, &cas)) {
|
||||
return false;
|
||||
continue;
|
||||
}
|
||||
uint64_t token_left =
|
||||
*reinterpret_cast<const uint64_t *>(token_bucket_data->data());
|
||||
LOG_DEBUG(absl::StrFormat(
|
||||
"ratelimit get token: id:%d, tokenBucketKey:%s, token left:%u", rule_id,
|
||||
tokenBucketKey, token_left));
|
||||
if (token_left == 0) {
|
||||
LOG_DEBUG(absl::StrFormat("get token failed, id:%d, tokenBucketKey:%s",
|
||||
rule_id, tokenBucketKey));
|
||||
return false;
|
||||
}
|
||||
token_left -= 1;
|
||||
@@ -52,12 +58,18 @@ bool getToken(int rule_id, const std::string &key) {
|
||||
tokenBucketKey,
|
||||
{reinterpret_cast<const char *>(&token_left), sizeof(token_left)}, cas);
|
||||
if (res == WasmResult::Ok) {
|
||||
LOG_DEBUG(
|
||||
absl::StrFormat("ratelimit token update success: id:%d, "
|
||||
"tokenBucketKey:%s, token left:%u",
|
||||
rule_id, tokenBucketKey, token_left));
|
||||
return true;
|
||||
}
|
||||
if (res == WasmResult::CasMismatch) {
|
||||
continue;
|
||||
}
|
||||
return false;
|
||||
LOG_WARN(absl::StrFormat("got invalid result:%d, id:%d, tokenBucketKey:%s",
|
||||
res, rule_id, tokenBucketKey));
|
||||
return true;
|
||||
}
|
||||
|
||||
LOG_WARN("get token failed with cas mismatch");
|
||||
@@ -86,12 +98,21 @@ void refillToken(const std::vector<std::pair<int, LimitItem>> &rules) {
|
||||
if (now - last_update < rule.second.refill_interval_nanosec) {
|
||||
continue;
|
||||
}
|
||||
LOG_DEBUG(
|
||||
absl::StrFormat("ratelimit rule need refilled, id:%s, "
|
||||
"lastRefilledKey:%s, now:%u, last_update:%u",
|
||||
id, lastRefilledKey, now, last_update));
|
||||
// Otherwise, try set last updated time. If updated failed because of cas
|
||||
// mismatch, the bucket is going to be refilled by other VMs.
|
||||
auto res = setSharedData(
|
||||
lastRefilledKey, {reinterpret_cast<const char *>(&now), sizeof(now)},
|
||||
last_update_cas);
|
||||
if (res == WasmResult::CasMismatch) {
|
||||
LOG_DEBUG(
|
||||
absl::StrFormat("ratelimit update lastRefilledKey casmismatch, the "
|
||||
"bucket is going to be refilled by other VMs, id:%s, "
|
||||
"lastRefilledKey:%s",
|
||||
id, lastRefilledKey));
|
||||
continue;
|
||||
}
|
||||
do {
|
||||
@@ -115,6 +136,10 @@ void refillToken(const std::vector<std::pair<int, LimitItem>> &rules) {
|
||||
last_update_cas)) {
|
||||
continue;
|
||||
}
|
||||
LOG_DEBUG(
|
||||
absl::StrFormat("ratelimit token refilled: id:%s, "
|
||||
"tokenBucketKey:%s, token left:%u",
|
||||
id, tokenBucketKey, token_left));
|
||||
break;
|
||||
} while (true);
|
||||
}
|
||||
@@ -138,6 +163,10 @@ bool initializeTokenBucket(
|
||||
setSharedData(tokenBucketKey,
|
||||
{reinterpret_cast<const char *>(&rule.second.max_tokens),
|
||||
sizeof(uint64_t)});
|
||||
LOG_INFO(absl::StrFormat(
|
||||
"ratelimit rule created: id:%s, lastRefilledKey:%s, "
|
||||
"tokenBucketKey:%s, max_tokens:%u",
|
||||
id, lastRefilledKey, tokenBucketKey, rule.second.max_tokens));
|
||||
continue;
|
||||
}
|
||||
// reconfigure
|
||||
@@ -172,6 +201,10 @@ bool initializeTokenBucket(
|
||||
}
|
||||
break;
|
||||
} while (true);
|
||||
LOG_INFO(absl::StrFormat(
|
||||
"ratelimit rule reconfigured: id:%s, lastRefilledKey:%s, "
|
||||
"tokenBucketKey:%s, max_tokens:%u",
|
||||
id, lastRefilledKey, tokenBucketKey, rule.second.max_tokens));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -169,6 +169,7 @@ bool PluginRootContext::checkPlugin(int rule_id,
|
||||
return true;
|
||||
}
|
||||
if (!getToken(rule_id, key)) {
|
||||
LOG_INFO(absl::StrCat("request rate limited by key: ", key));
|
||||
tooManyRequest();
|
||||
return false;
|
||||
}
|
||||
@@ -181,8 +182,7 @@ bool PluginRootContext::onConfigure(size_t size) {
|
||||
// Parse configuration JSON string.
|
||||
if (size > 0 && !configure(size)) {
|
||||
LOG_WARN("configuration has errors initialization will not continue.");
|
||||
setInvalidConfig();
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
const auto& rules = getRules();
|
||||
for (const auto& rule : rules) {
|
||||
@@ -191,7 +191,7 @@ bool PluginRootContext::onConfigure(size_t size) {
|
||||
}
|
||||
}
|
||||
initializeTokenBucket(limits_);
|
||||
proxy_set_tick_period_milliseconds(1000);
|
||||
proxy_set_tick_period_milliseconds(500);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user