Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/php/241.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript Ajax调用的服务器饱和_Javascript_Php_Ajax_Socket.io_Zeromq - Fatal编程技术网

Javascript Ajax调用的服务器饱和

Javascript Ajax调用的服务器饱和,javascript,php,ajax,socket.io,zeromq,Javascript,Php,Ajax,Socket.io,Zeromq,我正在Windows Server 2008上使用PHP over IIS 7.5 我的web应用程序在后台使用Ajax反复请求3个不同的JSON页面: 第1页每6秒 第2页每30秒 第3页每60秒 它们检索与某些表的当前状态相关的数据。这样我可以保持视图的更新 通常我不会遇到太多问题,但最近我看到我的服务器上满是数百个未响应的请求,我相信问题可能是由于其中一个请求的延迟造成的 如果每6秒请求一次的page1需要45秒才能响应(由于数据库查询速度慢或其他原因),那么在我看来,请求开始一个接一

我正在Windows Server 2008上使用PHP over IIS 7.5

我的web应用程序在后台使用Ajax反复请求3个不同的JSON页面:

  • 第1页每6秒
  • 第2页每30秒
  • 第3页每60秒
它们检索与某些表的当前状态相关的数据。这样我可以保持视图的更新

通常我不会遇到太多问题,但最近我看到我的服务器上满是数百个未响应的请求,我相信问题可能是由于其中一个请求的延迟造成的

如果每6秒请求一次的page1需要45秒才能响应(由于数据库查询速度慢或其他原因),那么在我看来,请求开始一个接一个地堆积起来。 如果有多个用户同时连接到web应用程序(或使用多个选项卡),情况可能会变得糟糕

有没有关于如何避免此类问题的建议

我曾考虑过使用一些东西,比如与一起使用,但由于我请求的数据不会被任何用户操作触发,我不知道如何从服务器端触发

我在考虑在客户端使用诸如ZMQ和Sockets.io之类的东西

这几乎肯定是长时间运行请求的最佳选择

…但由于我请求的数据不会从任何用户操作中触发,因此我不知道如何从服务器端触发

在这种情况下,所讨论的“用户操作”正在连接到socket.io服务器。此简化示例取自其中一个文档:


当触发“连接”事件时,您可以开始侦听ZMQ消息队列中的消息。如果需要,还可以启动长时间运行的查询。

这是一个非常糟糕的设置。如果可能,您应该始终避免轮询。将数据从服务器发送到客户端,而不是每6秒从客户端发送一次请求到服务器。您应该在服务器端检查数据是否有任何更改,然后使用WebSocket将数据传输到客户端。您可以在服务器端使用nodejs来监视数据中的任何更改。

我最终按照@epascarello的建议解决了这个问题,如果在X时间内没有得到响应,我会对它进行一些改进


如果请求尚未返回,请不要发送其他请求。但是修复服务器端代码并加快它的速度

基本上我是这样做的:

var ELAPSED_TIME_LIMIT = 5; //5 minutes
var responseAnswered = true;
var prevTime = new Date().getTime();

setInterval(function(){
    //if it was answered or more than X m inutes passed since the last call
    if(responseAnsswered &&  elapsedTime() > ELAPSED_TIME_LIMIT){
        getData()
        updateElapsedTime();
    }
}, 6000);

function getData(){
    responseAnswered = false;
    $.post("http://whatever.com/action.json", function(result){
        responseAnswered = true
    });
}

//Returns the elapsed time since the last time prevTime was update for the given element.
function elapsedTime(){
    var curTime = new Date().getTime();

    //time difference between the last scroll and the current one
    var timeDiff = curTime - prevTime;

    //time in minutes
    return (timeDiff / 1000) / 60;
}

//updates the prevTime with the current time
function updateElapsedTime(){
    prevTime = new Date().getTime();
}

让请求不花费45秒?或者不要每6秒请求一次?@DarkFalcon通常不需要45秒,但有时需要。我在寻求一种解决这个问题的方法。我认为用sockets.io实现它是个好主意。。类似的做法是使用“即使如此”来更新问题/答案投票/评论dynamically@MateiMihai但是什么会触发来自服务器端的消息呢?如果请求没有返回,请不要再发送另一个请求。但是修复服务器端代码并加快速度。谢谢你的回答,但我不太确定你说的是什么。我需要每6秒更新一次用户视图,对吗?视图如何从服务器端获取更新?在这里推送的是服务器端。WebSocket的行为与普通HTTP请求不同,消息可以向任意方向发送,而不仅仅是浏览器->服务器->浏览器。首先,从浏览器连接到websocket服务器,这将触发
连接
事件。从那时起,您的服务器可以直接向浏览器发送更新消息,而无需浏览器启动任何进一步的请求。我知道套接字是如何工作的。你不理解我的问题。这是PHP,不是javascript。我不能让一个进程运行setInterval函数来不时推送通知。必须有一些东西来推动客户。这就是我遇到的麻烦。抱歉,我完全没有看懂问题的第一行!我知道我可以使用node,但事实是web应用程序正在使用PHP,我无法改变这一点。此外,node还没有与oracledb和PLSQL过程完美集成。
var ELAPSED_TIME_LIMIT = 5; //5 minutes
var responseAnswered = true;
var prevTime = new Date().getTime();

setInterval(function(){
    //if it was answered or more than X m inutes passed since the last call
    if(responseAnsswered &&  elapsedTime() > ELAPSED_TIME_LIMIT){
        getData()
        updateElapsedTime();
    }
}, 6000);

function getData(){
    responseAnswered = false;
    $.post("http://whatever.com/action.json", function(result){
        responseAnswered = true
    });
}

//Returns the elapsed time since the last time prevTime was update for the given element.
function elapsedTime(){
    var curTime = new Date().getTime();

    //time difference between the last scroll and the current one
    var timeDiff = curTime - prevTime;

    //time in minutes
    return (timeDiff / 1000) / 60;
}

//updates the prevTime with the current time
function updateElapsedTime(){
    prevTime = new Date().getTime();
}