在我们的开发环境中,我们的功能应用程序通常仅需要几个服务器。
在周末,我们意外地引发了连锁反应,导致逐渐,持续地扩展至约140台服务器。现在,我们已经解决了基本问题并清除了队列,该活动似乎已恢复正常。 (Ph!)
奇怪的是,(30分钟后)我们仍然使所有这些服务器联机。我本以为他们会很快开始脱机,但是相反,我看到的“在线服务器”数量在110到140之间波动(上下波动)。绝大多数坐在那里0个请求/秒,没有CPU,没有内存。
所以,一些问题:
答案 0 :(得分:2)
只需在@Mikhail编写的内容中添加一些内容-您的函数比例如何取决于所使用的触发器的类型。如果使用队列,则运行时将查看队列的长度,并根据消息的数量向上/向下缩放。使用事件中心,此行为取决于中心中的分区数-您拥有的越多,就越渴望扩展功能。
可以查看源代码并尝试了解至少部分功能。实际上,它基于计时器和工作者的概念,它们会更新其状态并让运行时决定是否需要按比例放大或缩小。
总体算法如下:
protected virtual async Task MakeScaleDecision(string activityId, IWorkerInfo manager)
{
if (DateTime.UtcNow < _scaleCheckUtc)
{
return;
}
try
{
var workers = await _table.ListNonStale();
_tracer.TraceInformation(activityId, manager, workers.GetSummary("NonStale"));
if (await TryRemoveIfMaxWorkers(activityId, workers, manager))
{
return;
}
if (await TryAddIfLoadFactorMaxWorker(activityId, workers, manager))
{
return;
}
if (await TrySwapIfLoadFactorMinWorker(activityId, workers, manager))
{
return;
}
if (await TryAddIfMaxBusyWorkerRatio(activityId, workers, manager))
{
return;
}
if (await TryRemoveIfMaxFreeWorkerRatio(activityId, workers, manager))
{
return;
}
if (await TryRemoveSlaveWorker(activityId, workers, manager))
{
return;
}
}
catch (Exception ex)
{
_tracer.TraceError(activityId, manager, string.Format("MakeScaleDecision failed with {0}", ex));
}
finally
{
_scaleCheckUtc = DateTime.UtcNow.Add(_settings.ScaleCheckInterval);
}
}
此外,还可以在源代码中找到为什么看到活着的工人的答案:
protected virtual async Task PingWorker(string activityId, IWorkerInfo worker)
{
// if ping was unsuccessful, keep pinging. this is to address
// the issue where site continue to run on an unassigned worker.
if (!_pingResult || _pingWorkerUtc < DateTime.UtcNow)
{
// if PingWorker throws, we will not update the worker status
// this worker will be stale and eventually removed.
_pingResult = await _eventHandler.PingWorker(activityId, worker);
_pingWorkerUtc = DateTime.UtcNow.Add(_settings.WorkerPingInterval);
}
// check if worker is valid for the site
if (_pingResult)
{
await _table.AddOrUpdate(worker);
_tracer.TraceUpdateWorker(activityId, worker, string.Format("Worker loadfactor {0} updated", worker.LoadFactor));
}
else
{
_tracer.TraceWarning(activityId, worker, string.Format("Worker does not belong to the site."));
await _table.Delete(worker);
_tracer.TraceRemoveWorker(activityId, worker, "Worker removed");
throw new InvalidOperationException("The worker does not belong to the site.");
}
}
不幸的是,实现的某些部分是密封的(例如IWorkerInfo
),所以您无法了解全部情况,我们只能猜测(或询问;))
答案 1 :(得分:1)
Scale Controller是一项无记录行为的封闭源专有技术。您的问题没有官方答案。回答它的唯一方法是做您所做的事情:运行实验并进行测量。这种行为可能会随着时间而改变。
函数的确具有根据启发次数和资源利用率在何时扩展和何时扩展的启发式方法。过去,它们非常节俭,但是扩展速度不够好。现在,他们倾向于错误地配置太多而不是太多。
好消息是,除了出于好奇,您实际上不应该在意扩大规模。您不用为闲置的服务器付费。