我的应用程序最多可以在服务器端运行IO密集型的180个AJAX作业(长时间运行的SELECT
查询)。
我想优化我现有的多个CPU内核的负载,从依次执行每个AJAX调用的设计切换到其中最多并行执行4个请求的设计。
一个可能但很丑陋的解决方案是在客户端同时发出所有180个请求,并让服务器使用存储在Semaphore
或Session
级别的Application
。稍后我将讨论有关应用程序工作负载的信息。
我想找到一个更好的解决方案,在该解决方案中,所有调用均按顺序启动(表上的每一行都是不同的检查查询),但是当任何调用终止时,下一个启动,并且有多个(即4个)并发AJAX请求以及它们各自的装载机指示器。
我尝试使用Threadpool-js,但发现自己无法使用工作人员的jQuery
我当前的代码如下
function GlobalCheck() { //entry point
if (ValidateDate()) {
//Below are global variables
list = $(".chkClass:checked"); //Only checked rows deal to AJAX request
num = $(".chkClass:checked").length; //Total number of ajax calls
done = 0; //Count of complete calls. When it reaches num we are done!
if (list.length == 0) {
alert('...');
return;
}
$(".pMessage").fadeOut();
$(".tbStatus").html('');
$(".submit").hide();
$(".exportFunctions").fadeOut();
$(".loader").show();
$(":checkbox").attr('disabled', true);
SingleCheck(0); //simplification, I do other non interesting things here
}
}
function SingleCheck(index) {
aValue = $($(list).get(index)).val();
var splitted = aValue.split('_');
$('#loader_' + aValue).show();
$('#green_' + aValue).hide();
$('#yellow_' + aValue).hide();
$('#red_' + aValue).hide();
$('#print_' + aValue).hide();
$('#xls_' + aValue).hide();
$('#summ_' + aValue).hide();
$.ajax({
type: 'GET',
url: '@Url.Action("Single", "Check")',
data: {
pType: splitted[0],
pIdQuery: splitted[1],
pDateBegin: $('#date_begin').attr('value'),
pDateEnd: $('#date_end').attr('value'),
pNow: Math.floor(Math.random() * 1000000)
},
success: function (data) {
if (!CheckSessionExpired(data)) {
//alert(data);
$("#tdStatus_" + aValue).html(data);
$("#loader_" + aValue).hide();
done++; //Done 1 more query
$(".progress").each(function (i, cRow) { $(this).html([update status]); });
if (done == num) { // Finish?
FinishCheck();
}
else {
SingleCheck(done); //Go to the next
}
}
},
error: function (XMLHttpRequest, textStatus, errorThrown) {
alert(errorThrown);
RedirectToError();
}
});
}
结果如下:
问题是:在我的场景中,为了创建并发的AJAX请求,我可以遵循哪种方法?
[edit]忘记讨论应用程序需求:此应用程序正在实时运行,但没有为大量的用户群提供服务。当用户提交要检查的数据时,应用程序将执行密集的操作,同时长时间保持空闲状态。
最佳答案
$.ajax()
是一个异步函数,它会发起一个请求,然后立即返回。因此,如果您连续多次调用它,它将创建并发请求。
您的代码仍在单个线程上运行,但是HTTP请求在后台并行发生,并且jQuery在返回数据时调用您的回调。因此,您无需直接处理线程即可获得并行性。
在您的GlobalCheck()
中:
var CONCURRENT_REQUESTS = 4;
while (done < CONCURRENT_REQUESTS) {
SingleCheck(done++);
}
将启动四个并行请求,并且您的现有代码每次完成一个请求都会触发一个新请求,因此您将始终有4个并行请求正在运行。并且因为您的代码仅在单个线程上运行,所以您不必担心
done
变量等的并发问题。对于更多的并发请求,只需增加
CONCURRENT_REQUESTS
的值,但请注意,很快您将达到浏览器对单个域的并发请求的限制-每个浏览器的并发请求数有所不同,但始终很小。 See this answer for specifics。