我有一个与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
答案 0 :(得分:2)
两件事:
res.render
。可能是您连接的数据库在请求数量荒谬且从未触发回调之后断开与Express服务器的连接(并且没有database.on('close', function() { // Handle disconnect from DB, perhaps auto-restarting })
代码可以捕获它。getJSON
是一个jQuery方法?假设它是jQuery,那么你需要类似下面的内容
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自动完成,如果这就是您所追求的?),并且您可以从某些负载中保存服务器如果按键比服务器握手更快(可能是一个好的触摸打字员,几个小时的飞行距离)。