ExpressJS后端挂着太多的请求

时间:2012-03-14 14:29:29

标签: ajax node.js jsonp express sequelize.js

我有一个与Sequelize.js一起运行的快速应用程序作为ORM。我的快递应用程序接收来自我的主Rails应用程序的请求,并且由于跨域策略,这些请求是使用getJSON执行的。

在客户端上,当用户点击密钥时会触发请求。 一切都很顺利,每次用户点击密钥时,都会记录正在执行的查询(以及正在服务的json)。即使试图快速击中它也表现良好。但是,每当我按下按键(或者可能是几个客户端非常快地按下按键),当它开始发出大量请求时,服务器就会挂起,所有来自该点的请求都待处理(我看到了在Chrome开发工具的网络标签中,他们慢慢开始超时。我必须重启服务器才能让它再次响应。

我的请求的服务器代码是:

models.Comment.findAllPublic(req.params.pId, req.params.sId, function(comments){
                var json = comments.map(function(comment){
                    var com = {};
                    ['user_id','user_avatar', 'user_slug', 'user_name', 'created_at', 'text', 'private', 'is_speaker_note'].forEach(function(key){
                        com[key]=comment[key];
                    });
                    return com;
                });

                res.json({comments: json});
        }); 

来自Comment模型的findAllPublic方法(这是一个Sequelize模型)是:

findAllPublicAndMyNotes: function(current_user, presentationId, slideId, cb){
                db.query("SELECT * FROM `comments` WHERE  commentable_type='Slide' AND commentable_id=(SELECT id from `slides` where `order_in_presentation`="+slideId+" AND `presentation_id`="+presentationId+") AND (`private` IS FALSE OR (`private` IS TRUE AND `user_id`="+current_user+" AND `is_speaker_note` IS FALSE))",self.Comment).on('success', cb).on('failure',function(err){console.log(err);});
            }

如何避免服务器卡住?我是否在请求中留下了一些阻止代码,可能会在发出新请求时慢慢挂起服务器?

起初我认为这可能是一个问题,因为从Sequelize模型组成json对象时出现了“forEach”,但我也尝试将mysql查询的回调留空,只是响应空json并且它也被冻结了

也许这是mysql连接器的问题?当服务器卡住时,我通常可以运行mysql控制台并对我的数据库执行查询,它也会响应,所以我不知道这是不是问题。

我知道我可以控制关​​键事件以防止在长时间按下键时发出太多请求,但是当多个客户端反复并同时按下该键时,问题似乎也出现了。

有什么想法?在此先感谢您的帮助:D

1 个答案:

答案 0 :(得分:2)

两件事:

  1. 好像你有一些路径没有调用res.render。可能是您连接的数据库在请求数量荒谬且从未触发回调之后断开与Express服务器的连接(并且没有database.on('close', function() { // Handle disconnect from DB, perhaps auto-restarting })代码可以捕获它。
  2. 您的客户端代码应检测当按键上的AJAX请求在启动新的时仍处于挂起状态时,并取消旧的请求。我猜getJSON是一个jQuery方法?假设它是jQuery,那么你需要类似下面的内容
  3. var currKeyRequest = null;
    function callOnKeyUp() {
        var searchText = $('#myInputBox').value;
        if(currKeyRequest) {
            currKeyRequest.reject();
            currKeyRequest = null;
        }
        currKeyRequest = $.getJSON('path/to/server', function(json) {
            currKeyRequest = null;
            // Use JSON code
        });
    }
    

    这样,您减少了客户端的负载,自动完成功能的延迟(但是为什么不使用jQuery UI自动完成,如果这就是您所追求的?),并且您可以从某些负载中保存服务器如果按键比服务器握手更快(可能是一个好的触摸打字员,几个小时的飞行距离)。