-
Notifications
You must be signed in to change notification settings - Fork 4.9k
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
Support proactive checks in overload manager Api #18256
Changes from 3 commits
27f8ac0
ae0faab
b0afa36
9ef48cc
7e9319c
22a3389
edb87d6
d460ebc
5017e97
ce930d2
4787f8b
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,86 @@ | ||
#pragma once | ||
|
||
#include <string> | ||
|
||
#include "envoy/common/pure.h" | ||
#include "envoy/stats/scope.h" | ||
#include "envoy/stats/stats.h" | ||
|
||
#include "source/common/common/assert.h" | ||
#include "source/common/stats/symbol_table_impl.h" | ||
|
||
namespace Envoy { | ||
namespace Server { | ||
|
||
class ProactiveResourceMonitor { | ||
public: | ||
ProactiveResourceMonitor() = default; | ||
virtual ~ProactiveResourceMonitor() = default; | ||
/** | ||
* Tries to allocate resource for given resource monitor in thread safe manner. | ||
* Returns true if there is enough resource quota available and allocation has succeeded, false | ||
* otherwise. | ||
* @param increment to add to current resource usage value and compare against configured max | ||
* threshold. | ||
*/ | ||
virtual bool tryAllocateResource(int64_t increment) PURE; | ||
/** | ||
* Tries to deallocate resource for given resource monitor in thread safe manner. | ||
* Returns true if there is enough resource quota available and deallocation has succeeded, false | ||
* otherwise. | ||
* @param decrement to subtract from current resource usage value. | ||
*/ | ||
virtual bool tryDeallocateResource(int64_t decrement) PURE; | ||
/** | ||
* Returns current resource usage tracked by monitor. | ||
*/ | ||
virtual int64_t currentResourceUsage() const PURE; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Naive question: is the semantics of this to to block on that read or will implementors get the most recent read or? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Callers will get most recent read, added explanation to api docs. |
||
/** | ||
* Returns max resource usage configured in monitor. | ||
*/ | ||
virtual uint64_t maxResourceUsage() const PURE; | ||
}; | ||
|
||
using ProactiveResourceMonitorPtr = std::unique_ptr<ProactiveResourceMonitor>; | ||
|
||
class ProactiveResource { | ||
public: | ||
ProactiveResource(const std::string& name, ProactiveResourceMonitorPtr monitor, | ||
Stats::Scope& stats_scope) | ||
: name_(name), monitor_(std::move(monitor)), | ||
failed_updates_counter_(makeCounter(stats_scope, name, "failed_updates")) {} | ||
|
||
bool tryAllocateResource(int64_t increment) { | ||
if (monitor_->tryAllocateResource(increment)) { | ||
return true; | ||
} else { | ||
failed_updates_counter_.inc(); | ||
return false; | ||
} | ||
} | ||
|
||
bool tryDeallocateResource(int64_t decrement) { | ||
if (monitor_->tryDeallocateResource(decrement)) { | ||
return true; | ||
} else { | ||
failed_updates_counter_.inc(); | ||
return false; | ||
} | ||
} | ||
|
||
int64_t currentResourceUsage() { return monitor_->currentResourceUsage(); } | ||
|
||
private: | ||
const std::string name_; | ||
ProactiveResourceMonitorPtr monitor_; | ||
Stats::Counter& failed_updates_counter_; | ||
|
||
Stats::Counter& makeCounter(Stats::Scope& scope, absl::string_view a, absl::string_view b) { | ||
Stats::StatNameManagedStorage stat_name(absl::StrCat("overload.", a, ".", b), | ||
scope.symbolTable()); | ||
return scope.counterFromStatName(stat_name.statName()); | ||
} | ||
}; | ||
|
||
} // namespace Server | ||
} // namespace Envoy |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -5,13 +5,34 @@ | |
#include "envoy/common/pure.h" | ||
#include "envoy/event/scaled_range_timer_manager.h" | ||
#include "envoy/event/timer.h" | ||
#include "envoy/server/overload/proactive_resource_monitor.h" | ||
#include "envoy/thread_local/thread_local_object.h" | ||
|
||
#include "source/common/common/interval_value.h" | ||
|
||
namespace Envoy { | ||
namespace Server { | ||
|
||
enum class OverloadProactiveResourceName { | ||
GlobalDownstreamMaxConnections, | ||
}; | ||
|
||
class OverloadProactiveResourceNameValues { | ||
public: | ||
// Overload action to stop accepting new HTTP requests. | ||
const std::string GlobalDownstreamMaxConnections = | ||
"envoy.resource_monitors.global_downstream_max_connections"; | ||
|
||
std::set<std::string> proactive_resource_names_{GlobalDownstreamMaxConnections}; | ||
|
||
absl::flat_hash_map<std::string, OverloadProactiveResourceName> | ||
proactive_action_name_to_resource_ = { | ||
{GlobalDownstreamMaxConnections, | ||
OverloadProactiveResourceName::GlobalDownstreamMaxConnections}}; | ||
}; | ||
|
||
using OverloadProactiveResourceNames = ConstSingleton<OverloadProactiveResourceNameValues>; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The enum and this alias are almost the same apart from an 's'. Perhaps there's a better name? |
||
|
||
/** | ||
* Tracks the state of an overload action. The state is a number between 0 and 1 that represents the | ||
* level of saturation. The values are categorized in two groups: | ||
|
@@ -46,6 +67,32 @@ class ThreadLocalOverloadState : public ThreadLocal::ThreadLocalObject { | |
public: | ||
// Get a thread-local reference to the value for the given action key. | ||
virtual const OverloadActionState& getState(const std::string& action) PURE; | ||
/** | ||
* Invokes corresponding resource monitor to allocate resource for given resource monitor in | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Invokes the corresponding same below |
||
* thread safe manner. Returns true if there is enough resource quota available and allocation has | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. in a thread safe manner. Same below. |
||
* succeeded, false if allocation failed or resource is not registered. | ||
* @param name of corresponding resource monitor. | ||
* @param increment to add to current resource usage value within monitor. | ||
*/ | ||
virtual bool tryAllocateResource(OverloadProactiveResourceName resource_name, | ||
int64_t increment) PURE; | ||
/** | ||
* Invokes corresponding resource monitor to deallocate resource for given resource monitor in | ||
* thread safe manner. Returns true if there is enough resource quota available and deallocation | ||
* has succeeded, false if deallocation failed or resource is not registered. | ||
* @param name of corresponding resource monitor. | ||
* @param decrement to subtract from current resource usage value within monitor. | ||
*/ | ||
virtual bool tryDeallocateResource(OverloadProactiveResourceName resource_name, | ||
int64_t decrement) PURE; | ||
|
||
/** | ||
* TODO(nezdolik) remove this method once downstream connection tracking is fully moved to | ||
* overload manager. Checks if resource monitor is registered and resource usage tracking is | ||
* enabled in overload manager. Returns true if resource monitor is registered, false otherwise. | ||
* @param name of resource monitor to check. | ||
*/ | ||
virtual bool isResourceMonitorEnabled(OverloadProactiveResourceName resource_name) PURE; | ||
}; | ||
|
||
} // namespace Server | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -6,6 +6,7 @@ | |
#include "envoy/event/dispatcher.h" | ||
#include "envoy/protobuf/message_validator.h" | ||
#include "envoy/server/options.h" | ||
#include "envoy/server/overload/proactive_resource_monitor.h" | ||
#include "envoy/server/resource_monitor.h" | ||
|
||
#include "source/common/protobuf/protobuf.h" | ||
|
@@ -64,6 +65,26 @@ class ResourceMonitorFactory : public Config::TypedFactory { | |
std::string category() const override { return "envoy.resource_monitors"; } | ||
}; | ||
|
||
class ProactiveResourceMonitorFactory : public Config::TypedFactory { | ||
public: | ||
~ProactiveResourceMonitorFactory() override = default; | ||
|
||
/** | ||
* Create a particular proactive resource monitor implementation. | ||
* @param config const ProtoBuf::Message& supplies the config for the proactive resource monitor | ||
* implementation. | ||
* @param context ProactiveResourceMonitorFactoryContext& supplies the resource monitor's context. | ||
* @return ProactiveResourceMonitorPtr the resource monitor instance. Should not be nullptr. | ||
* @throw EnvoyException if the implementation is unable to produce an instance with | ||
* the provided parameters. | ||
*/ | ||
virtual ProactiveResourceMonitorPtr | ||
createProactiveResourceMonitor(const Protobuf::Message& config, | ||
ResourceMonitorFactoryContext& context) PURE; | ||
|
||
std::string category() const override { return "envoy.resource_monitors"; } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Whats the difference between this factory and the resource monitor factory? (Sorry if I'm being dense, they just look the same and I wonder whether they could be collapsed) Thanks There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The only difference is the return type for newly created monitor. We could have had instead two methods within |
||
}; | ||
|
||
} // namespace Configuration | ||
} // namespace Server | ||
} // namespace Envoy |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Seems like we're using both
uint64_t
andint64_t
in this interface, perhaps we can simplify on one to avoid lots of cast. Thoughts?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
switched all to int64_t