【问题标题】:Implementing concurrent processing in Web Service (ASMX), control Service performance在Web Service(ASMX)中实现并发处理,控制Service性能
【发布时间】:2014-09-08 13:18:19
【问题描述】:

这个问题是关于在 Web 服务 (ASMX) 中实现负载平衡的。不是 WCF。

我创建了 Web 服务 (ASMX) 并且我有一个 WebMethod:

[WebMethod(Description = "Extracting data from the image.")]
public PersonData GetInfo(byte[] image)
{
     PersonData data = new PersonData();
     IFlexiCaptureProcessor processor = fcWebServiceProcessorsPool.GetProcessor();
     processor.AddImageFile(image);
     IDocument document = processor.RecognizeNextDocument();
     data.Number = document.Sections[0];
     data.Date = document.Sections[1];
     return data;
}

我的 fcWebServiceProcessorsPool 中有 5 个处理器 - 处理器数量取决于 CPU 内核的数量。 我需要创建另一个 WebMethod:

[WebMethod]
public List<PersonData> GetInfo(List<byte[]> images)
{
   //foreach byte[] image in images
   //...the same code
}

但我不知道如何实现并发处理。 我的期望:

  • 1 个请求 = 100 个图像; 5 个处理器是空闲的 => 5 个加载的处理器 每张有 20 张图片。
  • 瞬间 6 个请求 = 1 个图像、1 个图像、20 个图像、30 个图像、40 个 图片,50 张图片; 5 个处理器空闲 => 5 个加载的处理器,1 个请求 排队。

1 个任务是 1 个图像。 我的目标 - 始终平等地加载每个处理器。

我该怎么做?这是我的第一个 Web 服务,所以我对此一无所知。我发现了很多关于 ThrottlingBehavior 的文章,但它指的是 WCF,但我的程序不是 WCF。我需要一些建议。

我使用我公司提供的 .NET Framework 4.5 和 dll 来处理图像。

【问题讨论】:

  • 在同一台计算机的 CPU 上进行负载平衡? ASP.NET 将在不同的线程上为每个请求提供服务(您可以在每个请求中并行工作),框架、操作系统和 CPU 本身将完成所有工作。 BTW 内核负载平衡并不是那么容易。例如,假设一个核心被提升而一个核心被关闭。唤醒那个沉睡的核心并减慢另一个核心或排队这样的请求是更好吗?如何管理缓存局部性? IMO 不会尝试管理这些细节,除非你真的清楚自己在做什么(而且 IMO ASP.NET 太高,无法清楚地了解它们)
  • 顺便说一句,ASMX 不再受支持。你应该考虑切换到Web API
  • 这个问题与负载均衡无关。这是并发/并行处理,由 TPL、PLINQ 和 TPL DataFlow 处理。 Web 框架的类型在这里无关紧要。重要的问题是你想对图像进行什么样的处理?哪个 .NET 框架?

标签: c# .net parallel-processing task-parallel-library


【解决方案1】:

您必须考虑哪些因素才能平衡 CPU/内核?很多事情,例如:

  • Turbo Boost(或同等技术)。如果您有两个以 3 GHz 运行的内核和两个处于睡眠状态的内核,那会更好吗?要唤醒另一个内核(将前两个内核减慢到 2 GHz)或将任务排队到这两个内核中?
  • 缓存局部性有什么好处?由于缓存(代码和/或数据)的原因,在同一个内核中将类似任务排队是否更有效?
  • 您对功耗有任何顾虑吗?
  • 所有内核负载均等?我不仅指您的程序,还指系统和后台服务/进程。
  • 您是否考虑了基本的 ASP.NET 基础结构?你知道它在哪里运行吗?此外,不同的 .NET/ASP.NET 版本表现不同,并且技巧可能不适用于另一个版本。

总的来说,从我的角度来看,这些细节实际上处于非常低的级别,并且在 ASP.NET 中,您无法清楚地了解系统中发生了什么。即使您进行了认真的研究并测量了结果,您可能得到的结果对于一个特定的场景(以及一个特定的 CPU/系统架构)都是有效的。调整这些东西是一件困难的事情,您需要详细信息(来自运行时)和测试(来自您收集统计数据的大量人群)。此外,即使您了解什么对您的场景更好,您也无法控制所有这些事情(例如,您无法以编程方式唤醒一个内核)。

ASP.NET 会在不同的线程中处理请求,你可以做的是并行计算。 .NET 框架、底层操作系统以及最后的 CPU 本身有更多细节可用于选择最佳方法,并且每一个都将为此协同工作。

您正在使用 C# 为 ASP.NET 编程,依赖这些经过严格测试和调整的组件更容易(也更安全)。

在代码中(假设现代 .NET 即使 .ASMX 听起来很旧,如果您在 .NET 2 上运行,您只需切换到直接在 ThreadPool 上排队的手工制作的 Parallel.ForEach 实现)。请注意,这只是我的意思的一个示例,而不是您应该在生产中真正使用的代码:

[WebMethod]
public List<PersonData> GetInfo(List<byte[]> images)
{
    var result = new ConcurrentBag<PersonData>();

    Parallel.ForEach(images, image => {
        result.Add(GetInfo(image));
    });

    return result.ToList();
}

给出答案:不要在意这些细节。使用您可以使用的最高工具(库、语言和框架)编写并行、可扩展和并发的代码,并让底层了解平衡。

【讨论】:

    猜你喜欢
    • 2014-05-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-09-02
    • 1970-01-01
    • 2011-10-07
    • 2018-01-11
    • 1970-01-01
    相关资源
    最近更新 更多