我有一个简单的Web应用程序模块,它基本上接受从移动客户端应用程序在PageLoad
上保存zip文件的请求。
现在,我想做的是解压缩文件并读取其中的文件并进一步处理它。包括将条目输入数据库。
更新:zip文件及其内容的大小将相当小,因此服务器不应承受太多负载。
更新2:我刚刚读到IIS何时对请求进行排队(在全局/应用程序级别)。那么这是否意味着我不需要实现复杂的请求处理机制,IIS 可以自己处理应用程序?
更新3:我正在寻找卸载下载zip的处理,不仅是为了最小化开销(在性能方面),也是为了避免在处理文件和更新记录时出现table-locking
的问题。在多个设备请求页面和后台任务处理数据库并行更新的情况下,将导致异常。
到目前为止,我已经将两个解决方案归零:
- 实现并发/消息队列
- 将文件处理代码实现到单独的工具中,并在服务器上计划作业以检查未处理的文件并串行处理它们。
倾向于我将尝试实现的Queuing Mechanism
因为它似乎不太依赖于配置。 v/s 在服务器端手动配置作业/计划。
那么,你们为此目的推荐我什么?
此外,在请求zip文件并将其保存在服务器端后,客户端和服务器端连接在这样做之后被释放。不想给我的 IIS 带来负担。
想象一下,几百个客户同时请求该页面。
实际上,我以前都没有使用过它们,因此任何示例或操作方法将不胜感激。
我推荐TPL和Rx扩展:您将解压缩的文件列表设置为可观察的集合,并为每个项目异步启动一个新任务。
我建议使用队列系统。
收到文件后,会将路径保存到线程同步队列中。同时,后台工作线程(或最好是另一台计算机)将检查此队列中的新文件,并将条目取消排队以处理它。
这样,您就不会启动未知数量的线程(每个 zip 文件),并且可以在一个位置处理 zip 文件。这样,当负载过重时,您还可以更轻松地将压缩处理代码移动到另一台计算机。您只需要访问一个公共队列。
最简单的方法可能是将静态Queue
与 lock
对象一起使用。它最容易实现,不需要外部资源。但这会导致在应用程序回收时队列丢失。
您提到丢失zip文件不是一种选择,那么如果您不想依赖外部资源,则此方法不是最好的。根据您的负载,可能值得使用外部资源 - 这意味着将 zip 文件上传到另一台计算机上的公共存储,并将消息添加到另一台计算机上的队列中。
下面是一个包含本地队列的示例:
ConcurrentQueue<string> queue = new ConcurrentQueue<string>();
void GotNewZip(string pathToZip)
{
queue.Enqueue(pathToZip); // Added a new work item to the queue
}
void MethodCalledByWorker()
{
while (true)
{
if (queue.IsEmpty)
{
// Supposedly no work to be done, wait a few seconds and check again (new iteration)
Thread.Sleep(TimeSpan.FromSeconds(5));
continue;
}
string pathToZip;
if (queue.TryDequeue(out pathToZip)) // If TryDeqeue returns false, another thread dequeue the last element already
{
HandleZipFile(pathToZip);
}
}
}
这是一个非常粗略的例子。每当 zip 到达时,您都会将路径添加到队列中。同时,一个后台工作线程(或多个,示例 s threadsafe)将处理一个又一个 zip,从队列中获取路径。zip 文件将按其到达的顺序进行处理。
您需要确保您的应用程序不会同时回收。但是,本地计算机上的所有资源都是这种情况,当计算机崩溃时,它们将丢失。
你过早地优化了。
您提到了表锁定 - 您使用的是哪种数据库?如果添加新行或更新现有行,大多数配置中的大多数现代数据库将:
- 使用行级锁定;和
- 足够快,无需担心锁定。
我建议从一个简单的方法开始
//Unzip
//Do work
//Save results to database
并获得一些证据,证明它太慢了。