2012-03-14 10 views
0

私はSequelize.jsをORMとして実行しているエクスプレスアプリを持っています。私のエクスプレスアプリはメインのRailsアプリからリクエストを受け取り、クロスドメインポリシーのためにこれらのリクエストはgetJSONで実行されます。リクエストが多すぎるExpressJSバックエンド

クライアントでは、ユーザーがキーを押すと要求が発生します。 すべてがうまくいって、ユーザーがキーを押すたびに、実行されているクエリ(およびjsonが提供されている)を記録します。すばやくヒットしようとしても、それはOKです。しかし、キーを押したままにしておくと(あるいは、いくつかのクライアントが非常に素早くキーに当たったとき)、要求が多く発せられる瞬間に、サーバがハングするだけで、その時点からのすべてのリクエストは保留されますChrome Dev Toolsの[ネットワーク]タブで)、ゆっくりタイムアウトし始めます。私はそれを再度応答させるためにサーバをリブートする必要があります。

私の要求のためのサーバー・コードは次のとおりです。

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

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)。 あなたはそれが関連していると思いますか?続編作者はまた、彼はコネクターを変更しようとしていると言います。 – scumah

+0

それ以外は、クライアントで保留中のリクエストを制御するためのソリューションを試しましたが、残念ながら、jqueryのgetJSONメソッドによって返されたオブジェクトは、Deferred要素の他のメソッドを実装していますが、rejectを実装していないようです。これに関する手掛かりは?ご協力いただきありがとうございます。 – scumah

+2

@scumah:フェリクスの作品の信用を失うことはありませんが、彼は自分自身があまりにも薄くなっていると思います。私は比較的単純なライブラリ(node-dateformat)に提出したパッチを見直したくないので、彼の前のライブラリをフォークしなければなりませんでした。その問題は、問題の原因となる可能性が高いと思われます。切断された場合、その障害でイベントが発生せず、再接続を試みません。 getJSONが "正しい"オブジェクトを提供していないことに関して、あなたはどのバージョンのjQueryを使用していますか?古いバージョンは単に '' XMLHttpRequest''オブジェクトを提供するだけで、 '' .abort() '' –

関連する問題