Merge pull request #7121 from Icinga/bugfix/concurrent-checks

Fix that MaxConcurrentChecks constant is overridden from 'checker' feature
This commit is contained in:
Michael Friedrich 2019-04-17 13:14:32 +02:00 committed by GitHub
commit 64568f5966
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 59 additions and 93 deletions

View File

@ -1156,7 +1156,7 @@ requires to use `cipher_list` compatible with the endpoint using the oldest vers
other tools to connect to the API ensure also compatibility with them as this setting affects not only inter-cluster other tools to connect to the API ensure also compatibility with them as this setting affects not only inter-cluster
communcation but also the REST API. communcation but also the REST API.
### CheckerComponent <a id="objecttype-checkcomponent"></a> ### CheckerComponent <a id="objecttype-checkercomponent"></a>
The checker component is responsible for scheduling active checks. The checker component is responsible for scheduling active checks.
This configuration object is available as [checker feature](11-cli-commands.md#cli-command-feature). This configuration object is available as [checker feature](11-cli-commands.md#cli-command-feature).
@ -1167,11 +1167,10 @@ Example:
object CheckerComponent "checker" { } object CheckerComponent "checker" { }
``` ```
Configuration Attributes: In order to limit the concurrent checks on a master/satellite endpoint,
use [MaxConcurrentChecks](17-language-reference.md#icinga-constants-global-config) constant.
Name | Type | Description This also applies to an agent as command endpoint where the checker
--------------------------|-----------------------|---------------------------------- feature is disabled.
concurrent\_checks | Number | **Optional and deprecated.** The maximum number of concurrent checks. Was replaced by global constant `MaxConcurrentChecks` which will be set if you still use `concurrent_checks`.
### CheckResultReader <a id="objecttype-checkresultreader"></a> ### CheckResultReader <a id="objecttype-checkresultreader"></a>

View File

@ -2215,11 +2215,11 @@ and developers have been working hard to add more REST API
clients and integrations into DevOps tools. clients and integrations into DevOps tools.
* [Libraries](12-icinga2-api.md#icinga2-api-clients-libraries) * [Libraries](12-icinga2-api.md#icinga2-api-clients-libraries)
* [Status](#icinga2-api-clients-status) * [Status](12-icinga2-api.md#icinga2-api-clients-status)
* [Management](#icinga2-api-clients-management) * [Management](12-icinga2-api.md#icinga2-api-clients-management)
* [Event Streams](#icinga2-api-clients-event-streams) * [Event Streams](12-icinga2-api.md#icinga2-api-clients-event-streams)
* [Actions](#icinga2-api-clients-actions) * [Actions](12-icinga2-api.md#icinga2-api-clients-actions)
* [REST API Apps](#icinga2-api-clients-apps) * [REST API Apps](12-icinga2-api.md#icinga2-api-clients-apps)
Additional [programmatic examples](12-icinga2-api.md#icinga2-api-clients-programmatic-examples) Additional [programmatic examples](12-icinga2-api.md#icinga2-api-clients-programmatic-examples)
will help you getting started using the Icinga 2 API in your environment. will help you getting started using the Icinga 2 API in your environment.

View File

@ -96,6 +96,12 @@ user has the capabilities to change to a different user.
If you still encounter problems, run the aforementioned CLI commands as root, If you still encounter problems, run the aforementioned CLI commands as root,
or with sudo. or with sudo.
### Configuration <a id="upgrading-to-2-11-configuration"></a>
The deprecated `concurrent_checks` attribute in the [checker feature](09-object-types.md#objecttype-checkercomponent)
has no effect anymore if set. Please use the [MaxConcurrentChecks](17-language-reference.md#icinga-constants-global-config)
constant in [constants.conf](04-configuring-icinga-2.md#constants-conf) instead.
## Upgrading to v2.10 <a id="upgrading-to-2-10"></a> ## Upgrading to v2.10 <a id="upgrading-to-2-10"></a>
### Path Constant Changes <a id="upgrading-to-2-10-path-constant-changes"></a> ### Path Constant Changes <a id="upgrading-to-2-10-path-constant-changes"></a>

View File

@ -282,8 +282,7 @@ static int Main()
#endif /* RLIMIT_STACK */ #endif /* RLIMIT_STACK */
} }
ScriptGlobal::Set("MaxConcurrentChecks", Application::GetDefaultMaxConcurrentChecks()); /* Calculate additional global constants. */
ScriptGlobal::Set("System.PlatformKernel", Utility::GetPlatformKernel(), true); ScriptGlobal::Set("System.PlatformKernel", Utility::GetPlatformKernel(), true);
ScriptGlobal::Set("System.PlatformKernelVersion", Utility::GetPlatformKernelVersion(), true); ScriptGlobal::Set("System.PlatformKernelVersion", Utility::GetPlatformKernelVersion(), true);
ScriptGlobal::Set("System.PlatformName", Utility::GetPlatformName(), true); ScriptGlobal::Set("System.PlatformName", Utility::GetPlatformName(), true);

View File

@ -60,14 +60,6 @@ void Application::OnConfigLoaded()
ASSERT(m_Instance == nullptr); ASSERT(m_Instance == nullptr);
m_Instance = this; m_Instance = this;
String reloadTimeout;
if (ScriptGlobal::Exists("ReloadTimeout"))
reloadTimeout = ScriptGlobal::Get("ReloadTimeout");
if (!reloadTimeout.IsEmpty())
Configuration::ReloadTimeout = Convert::ToDouble(reloadTimeout);
} }
/** /**
@ -406,14 +398,16 @@ pid_t Application::StartReloadProcess()
args.push_back("--validate"); args.push_back("--validate");
#endif /* _WIN32 */ #endif /* _WIN32 */
double reloadTimeout = Application::GetReloadTimeout();
Process::Ptr process = new Process(Process::PrepareCommand(new Array(std::move(args)))); Process::Ptr process = new Process(Process::PrepareCommand(new Array(std::move(args))));
process->SetTimeout(Configuration::ReloadTimeout); process->SetTimeout(reloadTimeout);
process->Run(&ReloadProcessCallback); process->Run(&ReloadProcessCallback);
Log(LogInformation, "Application") Log(LogInformation, "Application")
<< "Got reload command: Started new instance with PID '" << "Got reload command: Started new instance with PID '"
<< (unsigned long)(process->GetPID()) << "' (timeout is " << (unsigned long)(process->GetPID()) << "' (timeout is "
<< Configuration::ReloadTimeout << "s)."; << reloadTimeout << "s).";
return process->GetPID(); return process->GetPID();
} }
@ -1179,35 +1173,9 @@ int Application::GetDefaultRLimitStack()
return 256 * 1024; return 256 * 1024;
} }
/** double Application::GetReloadTimeout()
* Sets the max concurrent checks.
*
* @param maxChecks The new limit.
*/
void Application::SetMaxConcurrentChecks(int maxChecks)
{ {
ScriptGlobal::Set("MaxConcurrentChecks", maxChecks, true); return ScriptGlobal::Get("ReloadTimeout");
}
/**
* Retrieves the max concurrent checks.
*
* @returns The max number of concurrent checks.
*/
int Application::GetMaxConcurrentChecks()
{
Value defaultMaxConcurrentChecks = GetDefaultMaxConcurrentChecks();
return ScriptGlobal::Get("MaxConcurrentChecks", &defaultMaxConcurrentChecks);
}
/**
* Retrieves the default value for max concurrent checks.
*
* @returns The default max number of concurrent checks.
*/
int Application::GetDefaultMaxConcurrentChecks()
{
return 512;
} }
/** /**

View File

@ -77,9 +77,7 @@ public:
static int GetDefaultRLimitProcesses(); static int GetDefaultRLimitProcesses();
static int GetDefaultRLimitStack(); static int GetDefaultRLimitStack();
static int GetMaxConcurrentChecks(); static double GetReloadTimeout();
static int GetDefaultMaxConcurrentChecks();
static void SetMaxConcurrentChecks(int maxChecks);
static ThreadPool& GetTP(); static ThreadPool& GetTP();

View File

@ -25,7 +25,6 @@ String Configuration::PidPath;
String Configuration::PkgDataDir; String Configuration::PkgDataDir;
String Configuration::PrefixDir; String Configuration::PrefixDir;
String Configuration::ProgramData; String Configuration::ProgramData;
double Configuration::ReloadTimeout{300};
int Configuration::RLimitFiles; int Configuration::RLimitFiles;
int Configuration::RLimitProcesses; int Configuration::RLimitProcesses;
int Configuration::RLimitStack; int Configuration::RLimitStack;
@ -224,16 +223,6 @@ void Configuration::SetProgramData(const String& val, bool suppress_events, cons
HandleUserWrite("ProgramData", &Configuration::ProgramData, val, m_ReadOnly); HandleUserWrite("ProgramData", &Configuration::ProgramData, val, m_ReadOnly);
} }
double Configuration::GetReloadTimeout() const
{
return Configuration::ReloadTimeout;
}
void Configuration::SetReloadTimeout(double val, bool suppress_events, const Value& cookie)
{
HandleUserWrite("ReloadTimeout", &Configuration::ReloadTimeout, val, m_ReadOnly);
}
int Configuration::GetRLimitFiles() const int Configuration::GetRLimitFiles() const
{ {
return Configuration::RLimitFiles; return Configuration::RLimitFiles;

View File

@ -70,9 +70,6 @@ public:
String GetProgramData() const override; String GetProgramData() const override;
void SetProgramData(const String& value, bool suppress_events = false, const Value& cookie = Empty) override; void SetProgramData(const String& value, bool suppress_events = false, const Value& cookie = Empty) override;
double GetReloadTimeout() const override;
void SetReloadTimeout(double value, bool suppress_events = false, const Value& cookie = Empty) override;
int GetRLimitFiles() const override; int GetRLimitFiles() const override;
void SetRLimitFiles(int value, bool suppress_events = false, const Value& cookie = Empty) override; void SetRLimitFiles(int value, bool suppress_events = false, const Value& cookie = Empty) override;
@ -133,7 +130,6 @@ public:
static String PkgDataDir; static String PkgDataDir;
static String PrefixDir; static String PrefixDir;
static String ProgramData; static String ProgramData;
static double ReloadTimeout;
static int RLimitFiles; static int RLimitFiles;
static int RLimitProcesses; static int RLimitProcesses;
static int RLimitStack; static int RLimitStack;

View File

@ -94,11 +94,6 @@ abstract class Configuration
set; set;
}; };
[config, no_storage, virtual] double ReloadTimeout {
get;
set;
};
[config, no_storage, virtual] int RLimitFiles { [config, no_storage, virtual] int RLimitFiles {
get; get;
set; set;

View File

@ -5,6 +5,7 @@
#include "icinga/icingaapplication.hpp" #include "icinga/icingaapplication.hpp"
#include "icinga/cib.hpp" #include "icinga/cib.hpp"
#include "remote/apilistener.hpp" #include "remote/apilistener.hpp"
#include "base/configuration.hpp"
#include "base/configtype.hpp" #include "base/configtype.hpp"
#include "base/objectlock.hpp" #include "base/objectlock.hpp"
#include "base/utility.hpp" #include "base/utility.hpp"
@ -84,14 +85,15 @@ void CheckerComponent::Stop(bool runtimeRemoved)
wait += 0.1; wait += 0.1;
/* Pick a timeout slightly shorther than the process reload timeout. */ /* Pick a timeout slightly shorther than the process reload timeout. */
double waitMax = Configuration::ReloadTimeout - 30; double reloadTimeout = Application::GetReloadTimeout();
double waitMax = reloadTimeout - 30;
if (waitMax <= 0) if (waitMax <= 0)
waitMax = 1; waitMax = 1;
if (wait > waitMax) { if (wait > waitMax) {
Log(LogWarning, "CheckerComponent") Log(LogWarning, "CheckerComponent")
<< "Checks running too long for " << wait << "Checks running too long for " << wait
<< " seconds, hard shutdown before reload timeout: " << Configuration::ReloadTimeout << "."; << " seconds, hard shutdown before reload timeout: " << reloadTimeout << ".";
break; break;
} }
} }
@ -108,6 +110,7 @@ void CheckerComponent::Stop(bool runtimeRemoved)
void CheckerComponent::CheckThreadProc() void CheckerComponent::CheckThreadProc()
{ {
Utility::SetThreadName("Check Scheduler"); Utility::SetThreadName("Check Scheduler");
IcingaApplication::Ptr icingaApp = IcingaApplication::GetInstance();
boost::mutex::scoped_lock lock(m_Mutex); boost::mutex::scoped_lock lock(m_Mutex);
@ -126,7 +129,13 @@ void CheckerComponent::CheckThreadProc()
double wait = csi.NextCheck - Utility::GetTime(); double wait = csi.NextCheck - Utility::GetTime();
if (Checkable::GetPendingChecks() >= GetConcurrentChecks()) //#ifdef I2_DEBUG
// Log(LogDebug, "CheckerComponent")
// << "Pending checks " << Checkable::GetPendingChecks()
// << " vs. max concurrent checks " << icingaApp->GetMaxConcurrentChecks() << ".";
//#endif /* I2_DEBUG */
if (Checkable::GetPendingChecks() >= icingaApp->GetMaxConcurrentChecks())
wait = 0.5; wait = 0.5;
if (wait > 0) { if (wait > 0) {
@ -154,12 +163,12 @@ void CheckerComponent::CheckThreadProc()
Service::Ptr service; Service::Ptr service;
tie(host, service) = GetHostService(checkable); tie(host, service) = GetHostService(checkable);
if (host && !service && (!checkable->GetEnableActiveChecks() || !IcingaApplication::GetInstance()->GetEnableHostChecks())) { if (host && !service && (!checkable->GetEnableActiveChecks() || !icingaApp->GetEnableHostChecks())) {
Log(LogNotice, "CheckerComponent") Log(LogNotice, "CheckerComponent")
<< "Skipping check for host '" << host->GetName() << "': active host checks are disabled"; << "Skipping check for host '" << host->GetName() << "': active host checks are disabled";
check = false; check = false;
} }
if (host && service && (!checkable->GetEnableActiveChecks() || !IcingaApplication::GetInstance()->GetEnableServiceChecks())) { if (host && service && (!checkable->GetEnableActiveChecks() || !icingaApp->GetEnableServiceChecks())) {
Log(LogNotice, "CheckerComponent") Log(LogNotice, "CheckerComponent")
<< "Skipping check for service '" << service->GetName() << "': active service checks are disabled"; << "Skipping check for service '" << service->GetName() << "': active service checks are disabled";
check = false; check = false;

View File

@ -11,17 +11,8 @@ class CheckerComponent : ConfigObject
{ {
activation_priority 300; activation_priority 300;
[config, no_storage] int concurrent_checks { /* Has no effect. Keep this here to avoid breaking config changes. */
get {{{ [deprecated, config] int concurrent_checks;
return Application::GetMaxConcurrentChecks();
}}}
set {{{
Application::SetMaxConcurrentChecks(value);
}}}
default {{{
return Application::GetDefaultMaxConcurrentChecks();
}}}
};
}; };
} }

View File

@ -1,7 +1,9 @@
/* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */ /* Icinga 2 | (c) 2012 Icinga GmbH | GPLv2+ */
#include "icinga/clusterevents.hpp" #include "icinga/clusterevents.hpp"
#include "icinga/icingaapplication.hpp"
#include "remote/apilistener.hpp" #include "remote/apilistener.hpp"
#include "base/configuration.hpp"
#include "base/serializer.hpp" #include "base/serializer.hpp"
#include "base/exception.hpp" #include "base/exception.hpp"
#include <boost/thread/once.hpp> #include <boost/thread/once.hpp>
@ -20,6 +22,8 @@ void ClusterEvents::RemoteCheckThreadProc()
{ {
Utility::SetThreadName("Remote Check Scheduler"); Utility::SetThreadName("Remote Check Scheduler");
int maxConcurrentChecks = IcingaApplication::GetInstance()->GetMaxConcurrentChecks();
boost::mutex::scoped_lock lock(m_Mutex); boost::mutex::scoped_lock lock(m_Mutex);
for(;;) { for(;;) {
@ -27,7 +31,7 @@ void ClusterEvents::RemoteCheckThreadProc()
break; break;
lock.unlock(); lock.unlock();
Checkable::AquirePendingCheckSlot(Application::GetMaxConcurrentChecks()); Checkable::AquirePendingCheckSlot(maxConcurrentChecks);
lock.lock(); lock.lock();
auto callback = m_CheckRequestQueue.front(); auto callback = m_CheckRequestQueue.front();
@ -205,4 +209,4 @@ void ClusterEvents::LogRemoteCheckQueueInformation() {
<< m_ChecksExecutedDuringInterval * 6 * 15 << "/15min" << ");"; << m_ChecksExecutedDuringInterval * 6 * 15 << "/15min" << ");";
m_ChecksExecutedDuringInterval = 0; m_ChecksExecutedDuringInterval = 0;
} }

View File

@ -29,6 +29,7 @@ INITIALIZE_ONCE_WITH_PRIORITY(&IcingaApplication::StaticInitialize, 50);
void IcingaApplication::StaticInitialize() void IcingaApplication::StaticInitialize()
{ {
/* Pre-fill global constants, can be overridden with user input later in icinga-app/icinga.cpp. */
String node_name = Utility::GetFQDN(); String node_name = Utility::GetFQDN();
if (node_name.IsEmpty()) { if (node_name.IsEmpty()) {
@ -43,6 +44,9 @@ void IcingaApplication::StaticInitialize()
ScriptGlobal::Set("NodeName", node_name); ScriptGlobal::Set("NodeName", node_name);
ScriptGlobal::Set("ReloadTimeout", 300);
ScriptGlobal::Set("MaxConcurrentChecks", 512);
Namespace::Ptr systemNS = ScriptGlobal::Get("System"); Namespace::Ptr systemNS = ScriptGlobal::Get("System");
/* Ensure that the System namespace is already initialized. Otherwise this is a programming error. */ /* Ensure that the System namespace is already initialized. Otherwise this is a programming error. */
VERIFY(systemNS); VERIFY(systemNS);
@ -289,6 +293,12 @@ String IcingaApplication::GetNodeName() const
return ScriptGlobal::Get("NodeName"); return ScriptGlobal::Get("NodeName");
} }
/* Intentionally kept here, since an agent may not have the CheckerComponent loaded. */
int IcingaApplication::GetMaxConcurrentChecks() const
{
return ScriptGlobal::Get("MaxConcurrentChecks");
}
String IcingaApplication::GetEnvironment() const String IcingaApplication::GetEnvironment() const
{ {
return Application::GetAppEnvironment(); return Application::GetAppEnvironment();

View File

@ -33,6 +33,8 @@ public:
String GetNodeName() const; String GetNodeName() const;
int GetMaxConcurrentChecks() const;
String GetEnvironment() const override; String GetEnvironment() const override;
void SetEnvironment(const String& value, bool suppress_events = false, const Value& cookie = Empty) override; void SetEnvironment(const String& value, bool suppress_events = false, const Value& cookie = Empty) override;

View File

@ -218,7 +218,7 @@ void ConfigPackageUtility::AsyncTryActivateStage(const String& packageName, cons
args->Add("ActiveStageOverride=" + packageName + ":" + stageName); args->Add("ActiveStageOverride=" + packageName + ":" + stageName);
Process::Ptr process = new Process(Process::PrepareCommand(args)); Process::Ptr process = new Process(Process::PrepareCommand(args));
process->SetTimeout(Configuration::ReloadTimeout); process->SetTimeout(Application::GetReloadTimeout());
process->Run(std::bind(&TryActivateStageCallback, _1, packageName, stageName, reload)); process->Run(std::bind(&TryActivateStageCallback, _1, packageName, stageName, reload));
} }