0

我们使用SharpZipLib。我们需要能够解压缩服务器上的文件并将它们放在单独的文件夹中。解压缩文件的请求将来自网页上的用户。我想如果文件足够大,解压缩需要很长时间。我们不希望用户在等待解压缩完成以继续浏览网站时卡在页面上。

处理这种情况的好方法是什么:分离一个不同的线程来处理解压缩文件,创建一个单独的 Windows 服务来解压缩文件,或者......什么?

通过单独的线程或窗口服务来做这件事的利弊是什么?

4

4 回答 4

1

单独流程的优势 在单独流程中
完成的工作可以在时间和物理上以及从安全的角度与页面流解耦。及时解耦:如果您选择,您可以缓冲解压缩内容的请求,直到“稍后”负载较低且有空闲 CPU 周期来执行此操作。

也在物理上解耦;对于大型系统,您可以有多个工作进程,甚至部署在多台独立的机器上,异步完成这项工作,并且该处理层可以独立于网页处理进行扩展。在任何系统中都存在瓶颈,分布式部署的优势是您可以独立扩展单独的工作负载,以更有效地消除瓶颈。

不过我想说,后一种好处只在非常大规模的系统中有用。在大多数情况下,您不会拥有从独立物理扩展层中受益的那种交易量。这不仅适用于您的工作负载,而且适用于所有工作负载的 98%。YAGNI 原则也适用于可扩展性。

物理解耦还允许独立开发不同的工作负载(页面流和 zip 解包)。换句话说,假设工作项不是简单的“解压缩文件”,而是更复杂的东西,其中包含多个步骤和决策点。在单独的进程中设计工作处理器允许独立于工作项处理来构建和测试页面流。如果它们必须独立发展,这可能是一个很好的优势。

如果工作项将通过不同的渠道到达,这种物理解耦也很好。假设网页不是工作项到达的唯一途径。假设您有一个 ftp 分站、一个 Web 服务或一个机器监控的邮箱,它们也可以接收工作项。在这种情况下,将工作项处理与网页处理物理分离是有意义的。

最后,这些东西在运行时的安全性上是解耦的。在某些 Web 应用服务器部署中,安全规则禁止 Web 服务器写入磁盘 - Web 服务器没有可写磁盘存储。单独的异步工作进程可以部署在网络的单独部分,具有大量存储空间,并且可能受到一组单独的安全要求的限制。这可能适用于您,也可能不适用于您。

线程处理
的优点 在单独的线程中完成工作的优点是它更简单。解耦引入了复杂性和成本。在单独的线程中管理工作,您没有任何管理单独进程(可能是单独的机器)的操作开销。没有额外的配置,没有新的构建/部署步骤。无需额外备份。无需维护额外的安全身份。无需担心通信交换(除了线程调度)。

您可以选择对工作项处理进行更复杂的处理,并且可以选择在 zip 文件看起来足够小的时候同步执行工作。假设您建立了 4 秒响应时间的阈值 - 高于该阈值,您需要异步工作负载,低于 4 秒,您将其“内联”。当然,您永远无法确定一个 zipfile 需要多长时间,但您可以根据文件的大小建立一个好的启发式方法。无论您是使用外部进程进行异步工作还是使用单独的线程,都可以使用此优化,但老实说,使用单独的线程时利用优化更简单。更少的额外工作要做。所以这是线程方法的一个优势。

非差异化
因素 如果您选择使用 AJAX 轮询机制来通知工作项状态,则可以与单独的进程或单独的线程一起使用。我不知道您将如何进行工作项跟踪,但我想当一个特定的工作项(zip 文件?)完成后,您将更新某处的记录——文件系统中的文件,数据库中的表. 无论是由同一进程中的线程还是由单独的进程(Windows 服务)完成,都会发生该更新。因此,无论您的架构决定如何,轮询的 AJAX 客户端在任何情况下都只会检查 db 表或文件系统,并且将以相同的方式获得工作项状态的通知。

如何决定
理论很有趣,但最终毫无用处,没有实际的操作限制。

工作量是现实世界的关键项目之一。您没有说这些 zip 文件有多大,但我猜它们是“常规大小”。大约4GB或更少的东西。通常,像这样的 zipfile 在我的笔记本电脑上解压缩需要 20-60 秒,但当然在具有真实存储系统和更快 CPU 的服务器上,它会更少。您也没有描述事务的并发性——任何时候会发生多少这样的事情。我假设并发性不是特别高。

如果是这种情况,我会坚持使用更简单的异步线程方法。您在 ASP.NET 中执行此操作,我假设在服务器操作系统上。CLR 具有良好的线程管理,而 ASP.NET 具有良好的进程横向扩展能力。因此,即使在高工作负载下,您也将获得良好的 CPU 利用率和规模,而无需大量配置工作。

如果工作项运行时间更长——比如说大约几小时甚至几天,并且时间是不可预测的(比如关闭股票订单)——那么在这种情况下,我会倾向于异步流程。如果并发性是每秒数千次,或者再次非常不可预测,那也将推荐一个单独的进程。如果故障模式足够复杂,我可能希望工作项位于单独的进程中以管理它。如果工作项处理可能会定期更改(根据不断变化的业务条件添加一个额外的步骤),我可能希望它在一个单独的流程中。

但在您的情况下,这些事情似乎都不是真的 - 解压缩 zip 文件。

于 2009-05-15T03:35:46.500 回答
1

单独线程的缺点是:

  1. 当页面结束时,没有简单的方法可以获取有关其他线程正在做什么的通知。
  2. 应用程序可以随时重新启动。
  3. 如果用户快速连续提交两次页面,很容易意外启动两次。
  4. 多线程代码很难调试。

单独线程的优点是:

  1. 更少的代码
  2. 如果解压缩完成时不需要通知用户,则很容易触发并忘记。
  3. 无需额外的安装工作。

windows服务的优缺点与上面大致相反。

于 2009-05-15T03:46:31.047 回答
0

就我个人而言,我会沿着 Windows 服务路线走下去,并在它们之间传递消息以获得进展,例如将 a 返回handle到可用于监视状态的解压缩。

但是,您也可以我认为也许分拆一个线程来执行此操作,这将愉快地执行并返回页面。

于 2009-05-14T14:42:08.530 回答
0

我会使用一个异步进程,您可以轻松地从启用 AJAX 的页面进行轮询。完成后,页面的 AJAX 部分可以呈现您在用户等待进程同步完成时通常会呈现的详细信息。

于 2009-05-14T14:43:42.160 回答