3

我有一个网站,用户可以在其中上传 PDF 并将其转换为 WORD doc。

它工作得很好,但有时(每小时 5-6 次)用户必须比平时等待更多的时间才能进行转换......

我使用 ASP.NET MVC,流程是: - 用户上传文件 -> 获取流并将其转换为 word ->word 文件保存为临时文件 ->向用户返回url

我不确定是否必须将此流转换为异步?基本上,我的流程现在是连续的,但我每秒大约有 3-5 个请求,CPU 是双核和 4 GB 内存。

据我所知maxConcurrentRequestsPerCPU is 5000;还有The default value of Threads Per Processor Limit is 25;所以这些默认设置应该很好,对吧?

那为什么我的网络应用程序有时会“等待”?是否有任何 IIS 设置需要从默认修改为其他设置,或者我应该将我的同步方法设置为异步转换?

Ps:转换本身需要 1 秒到 40-50 秒,具体取决于 pdf 文件的大小。

更新:基本上对我来说不太清楚的是:如果用户上传文件并且转换时间很长,不应该只是当前请求因此而“受苦”吗?因为下一个请求是独立的,所以进行另一个 CPU 调用和不同的线程,所以这里不应该等待,不是吗?

4

1 回答 1

1

这里有几件事必须明确定义。至少据我所知,Async(hronous) 方法和流程不是一回事。

异步方法(使用 Task,通常也利用 async/await 关键字)将以下列方式工作:

  1. 执行从线程 t1 开始,直到它到达等待
  2. (可能)长时间操作不会发生在线程 t1 上——有时甚至根本不会发生在应用程序线程上,利用 IOCP(I/O 完成端口)。
  3. 线程 t1 空闲并释放回线程池,并准备好在需要时为其他请求提供服务
  4. 当(可能)长操作返回时,从线程池中获取一个线程(甚至可能是相同的 t1,或者很可能是另一个),其余的代码执行从遇到的最后一个等待恢复
  5. 其余代码执行

这里有几点需要注意:

一个。客户端在整个过程中被阻塞。线程的最终切换等仅发生在服务器上 b。这种方法主要是为了缓解一种叫做“线程饥饿”的不想要的情况。这并不意味着加快客户的总等待时间,而且通常不会加快进程。

据我了解,异步流程至少在这种情况下意味着,在用户请求转换文档后,客户端(即客户端的浏览器)将很快收到一个响应,其中通知他这服务器上可能已经开始了很长的过程,用户应该耐心等待,当前的响应页面可能会提供进度反馈。


在您的情况下,我推荐第二种方法,因为第一种方法根本没有帮助。

当然,这并不容易。您需要模拟一个队列,您需要一个处理代理和一个驱逐策略(如果您不想要第二个代理,很可能由同一个代理强制执行)。

这将按照以下方式工作:

一个。最终用户提交一个文件,Web 服务器接收它 b. Web 服务器将其放入队列并接收作业编号 c。Web 服务器向用户返回一个带有作业编号的响应(假设是一个带有轮询机制的 HTML 页面,该机制会定期从服务器接收进度) d。代理将在有机会时开始处理文档(即完成其他工作)并在公共位置更新其状态以供 Web 服务器选择此信息 e.Web 服务器将接收来自 HTML 响应的调用,询问作业的状态,并会发现作业已完成并提供下载链接或直接开始下载。

这可以通过某些方式进行细化:

  1. 可以使用websockets或长轮询(例如SignalR覆盖两者)代替客户端轮询服务器
  2. 如果硬件配置合理,可以使用许多处理代理而不是一个

队列可以用一个简单的 RDBMS 来实现,Remus Ruşanu 有一篇关于这个的好文章

于 2016-07-07T20:17:47.787 回答