2012-03-14 3 views
0

Sequelize.js를 ORM으로 실행중인 익스프레스 앱이 있습니다. 익스프레스 앱은 주요 Rails 앱에서 요청을받으며 도메인 간 정책으로 인해 이러한 요청은 getJSON을 통해 수행됩니다.너무 많은 요청으로 인해 ExpressJS 백엔드가 걸려 있습니다.

클라이언트에서 사용자가 키를 누를 때 요청이 시작됩니다. 모든 것이 잘되고 익스프레스는 사용자가 키를 누를 때마다 수행되는 쿼리 (및 json이 제공됨)를 기록합니다. 빨리 치는 것을 시도조차 그것은 ok를 실행한다. 하지만 키를 눌렀을 때 (또는 여러 클라이언트가 키를 매우 빠르게 누르는 경우) 요청이 많이 발생하기 시작하면 잠시 서버가 멈추고 그 시점의 모든 요청이 보류 상태가됩니다. Chrome Dev Tools의 Network 탭에서), 천천히 타임 아웃되기 시작합니다. 다시 응답하도록 서버를 재부팅해야합니다.

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}); 
     }); 

그리고 코멘트 모델에서 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

autosuggest와 같은 것을 만들면 되나요? –

답변

2

두 가지 :

  1. 당신이 res.render가 호출되지 않는 몇 가지 경로를 가지고있는 것처럼 보인다. 불합리한 수의 요청과 콜백이 실행되지 않으면 연결하려는 데이터베이스가 Express 서버에 연결을 끊을 수 있습니다 (그리고이를 잡을 코드는 database.on('close', function() { // Handle disconnect from DB, perhaps auto-restarting })입니다.)
  2. 클라이언트 측 코드는 키를 누를에 AJAX 요청이 아직 새 시작되는 동안 대기 때 감지하고 이전을 취소합니다. 내가 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 자동 완성 기능을 사용하는 이유는 무엇입니까?). 또한 키 누르기가 더 빠르면 일부로드에서 서버를 저장할 수 있습니다 서버와의 핸드 쉐이킹보다 (좋은 터치 타이피스트로 몇 시간 거리에서 가능).

+0

안녕하세요, 귀하의 답변 주셔서 감사 드리며,이 문제와 관련이 있다고 생각되는 정보를 찾았습니다. 내가 개발중인 것은 실시간 프레젠테이션 시스템이며 사용자가 앞으로/뒤로 키를 누를 때 슬라이드가로드되고 해당 슬라이드에 대한 사용자의 의견도로드됩니다. 그래서 그것은 자동 완성이 아닙니다 :). 귀하의 의견에 감사 드리며, 지금은 sequelize.js가 node-mysql 커넥터를 사용하고 있음을 발견했습니다. 여기서 [열린 문제] (https://github.com/felixge/node-mysql/issues/)를 찾을 수 있습니다. 113). 관련이있을 것으로 생각하십니까? sequelize 저자는 또한 그가 커넥터를 바꿀 것이라고 말했습니다. – scumah

+0

그 외에도 클라이언트에서 보류중인 요청을 제어하기위한 솔루션을 시도했지만 불행히도 jquery의 getJSON 메서드에서 반환 된 개체는 Deferred 요소의 다른 메서드를 구현하지만 reject를 구현하지 못하는 것으로 보입니다. 이것에 대한 단서가 있습니까? 당신의 도움을 주셔서 감사합니다. – scumah

+2

@scumah : 펠릭스의 일에 의심을 품지는 않겠지 만, 그는 너무 얇게 퍼졌다 고 생각합니다. 나는 비교적 단순한 라이브러리 (node-dateformat)에 제출 한 패치를 검토하기를 원하지 않았기 때문에 그의 라이브러리를 포크 화해야했습니다. 이 문제는 문제의 원인이 될 수 있다고 생각됩니다. 연결이 끊어지면 오류가 발생하지 않고 다시 연결을 시도하지 않습니다. getJSON이 "올바른"객체를 제공하지 않는다면 jQuery의 어떤 버전을 사용하고 있습니까? 이전 버전은''XMLHttpRequest'' 객체를 제공하기 만하면''.abort()''할 수 있습니다. –