原谅标题,我不太确定如何说出我要找的东西,或者我是否知道我在寻找什么。
我有一个正在运行的服务,它同时需要大量的请求。另外,在服务中,我必须向外部服务发出一定数量(通常是10-15)的请求,这是我并行运行的。这段代码如下所示
Task<IResponse>[] tasks = new Task<IResponse>[Adapters.Count];
for(int i = 0; i < Adapters.Count;i++)
{
IAdapter adapter = Adapters[i];
Func<IResponse> makeExternalHttpRequest= () => adapter.MakeExternalHttpRequest(element, mappings);
tasks[i] = Task.Factory.StartNew<IResponse>(() =>
{
try
{
var result = makeExternalHttpRequest();
if (!token.IsCancellationRequested)
{
return result;
}
}catch(Exception exception)
{
}
return null;
}, token);
};
var timeout = ...some timeout value
Task.WaitAll(tasks,timeout, token);
tokenSource.Cancel();
for (int i = 0; i < tasks.Length; i++)
{
if (tasks[i].Result != null)
{
if (tasks[i].IsCompleted)
{
results.Add(tasks[i].Result);
}
}
}
在过去的6-7个月里,一切似乎都按照我的预期运行,然后昨天,服务器停机了,我从系统管理员那里收到了以下信息。
如果您注意到突出显示的区域,则它在经过的时间内非常大。
我猜这有助于服务器停机的原因,但我们仍在调查发生了什么。
对于发生了什么以及接下来的步骤应该是什么?
答案 0 :(得分:0)
我认为您接下来的步骤应该是收集更多信息。编写代码的方式,您的请求将在超时到期后立即返回(或者所有任务完成后,以先到者为准)。其他任务将在后台自行运行完成,假设makeExternalHttpRequest()
方法最终超时,它们将在自己的时间内完全停止。
您的取消令牌没有做任何有用的事情,因为代码将在其上方的行上阻止。
我要做的是弄清楚哪个外部请求花费的时间最长,并在发生这种情况时记录警告。那么至少你会有更好的信息来了解正在发生的事情。请参阅此pesudo代码:
(上面某处,创建一个记录器和System.Diagnostics.Stopwatch
try
{
var result = makeExternalHttpRequest();
if(stopwatch.Elapsed > SomeUnreasonableTimespan)
logger.Warn("Task exceeded reasonable execution period." + TaskData);
if (!token.IsCancellationRequested)
{
return result;
}
}catch(Exception exception)
{
}
return null;
作为一般性评论,我发现这条信息最有用:
在过去的6-7个月里,一切似乎都按照我的预期运行,然后昨天,服务器停机了,我从系统管理员那里收到了以下信息。
这意味着问题可能与您的代码无关,但与其他内容有关。当我进行故障排除时,我倾向于忽略那些没有改变的事情,并专注于那些事情。服务器不时会崩溃。您需要担心的是他们大多数时间都满足您的要求吗?如果是这样,那么我不会太担心这段代码。