0

原谅标题,我不太确定如何表达我在寻找什么,或者我什至知道我在寻找什么。

我有一个正在运行的服务,它可能同时接受大量请求。此外,在服务中,我必须向外部服务发出一定数量(通常为 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 个月里,一切似乎都按我的预期工作,然后昨天,服务器出现故障,我们的系统管理员向我发送了以下信息。

在此处输入图像描述

如果您注意到突出显示的区域,则表示经过的时间相当大。

我猜这导致了服务器宕机的原因,但我们仍在调查发生了什么。

关于发生了什么以及我的下一步应该是什么的任何想法?

4

1 回答 1

0

我真的认为您的下一步应该是收集更多信息。按照代码的编写方式,您的请求将在超时到期后(或所有任务完成后,以先到者为准)立即返回。其他任务将在后台自行运行完成,并假设该makeExternalHttpRequest()方法最终超时,它们都会在自己的时间内停止运行。

您的取消令牌没有做任何有用的事情,因为代码将在其上方的行上阻塞。

我要做的是找出哪些外部请求花费的时间最长,并可能在发生这种情况时记录一个警告。然后,至少您将获得有关正在发生的事情的更好信息。请参阅此伪代码:

(在上面的某个地方,创建一个记录器和一个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 个月里,一切似乎都按我的预期工作,然后昨天,服务器出现故障,我们的系统管理员向我发送了以下信息。

这意味着问题可能与您的代码无关,而是与其他内容有关。当我进行故障排除时,我倾向于忽略没有改变的事情,而专注于已经改变的事情。服务器会不时崩溃。您需要担心的是它们是否大部分时间都满足您的要求?如果是这样,那么我不会太担心这段代码。

于 2013-03-21T00:00:05.883 回答