5

我有一个运行各种服务器扫描的服务。有问题的网络可能很大(数十万个网络节点)。

该软件的当前版本正在使用我们设计的队列/线程架构,它可以工作但效率不高(尤其是因为作业可能会产生处理不好的子代)

V2 即将推出,我正在考虑使用 TPL。似乎它应该非常适合。

我看过这个问题,答案意味着 TPL 可以处理的任务没有限制。在我的简单测试中(启动 100,000 个任务并将它们交给 TPL),TPL 很早就出现了内存不足异常(很公平——尤其是在我的开发箱上)。

扫描需要可变长度的时间,但 5 分钟/任务是一个很好的平均值。

您可以想象,扫描大型网络可能需要相当长的时间,即使在强大的服务器上也是如此。

我已经有了一个框架,它允许扫描作业(存储在 Db 中)在多个扫描服务器之间拆分,但问题是我应该如何将工作准确地传递给特定服务器上的 TPL。

我可以监控 TPL 队列的大小并(比如说)在它低于几百个条目时将其加满吗?这样做有缺点吗?

我还需要处理需要暂停扫描的情况。与取消/重置可能已经部分处理的任务相比,不将工作交给 TPL 似乎更容易做到这一点。

所有初始任务都可以按任何顺序运行。子项必须在父项开始执行后运行,但由于父项生成它们,所以这不应该成为问题。孩子们可以按任何顺序运行。因此,我目前设想将子任务写回 Db,而不是直接生成到 TPL 中。如果需要,这将允许其他服务器“工作窃取”。

有没有人以这种方式使用 TPL 的经验?有什么我需要注意的注意事项吗?

4

1 回答 1

11

TPL 是关于启动小型工作单元并并行运行它们。这不是监控、暂停或限制这项工作。

您应该将 TPL 视为启动“工作”和同步线程的低级工具。

关键点:TPL 任务!= 逻辑任务。在您的情况下,逻辑任务是扫描任务(“扫描从 x 到 y 的 IP 范围”)。这样的任务不应该对应于物理任务“System.Threading.Task”,因为两者是不同的概念。

您需要自己安排、编排、监控和暂停逻辑任务,因为 TPL 不理解它们并且无法执行。

现在更实际的问题:

  1. TPL 肯定可以在没有 OOM 的情况下启动 100k 个任务。发生 OOM 是因为您的任务代码耗尽了内存。
  2. 扫描网络听起来像是异步代码的一个很好的例子,因为当您扫描时,您可能会等待结果,同时具有很大程度的并行性。您可能不希望进程中有 500 个线程都在等待网络数据包到达。异步任务非常适合 TPL,因为您运行的每个任务都变得纯粹受 CPU 限制且很小。这就是 TPL 的最佳选择。
于 2012-06-19T11:58:08.803 回答