11

djangoで(AJAXロングポーリングを使用して)リアルタイムの最近のアクティビティフィードを開発する必要がありますが、サーバー側の最善の戦略は何でしょうか。

擬似コード:

def recent_activity_post_save():
    notify_view()

[in the view]
while not new_activity():
    sleep(1)
return HttpResponse(new_activity())

最初に頭に浮かぶのは、毎秒DBにクエリを実行することです。現実的ではありません。別のオプション:

  1. 通知サービスとしてキャッシュを使用する
  2. セロリのような特殊なツールを使用する(やり過ぎのように見えるので、私はそれをしたくない)

ここに行くための最良の方法は何ですか?

4

8 に答える 8

5

シンプルに保つことをお勧めします...

イベントを格納するデータベーステーブルを作成し、必要に応じてそのテーブルに挿入してから、単純なajaxポーリング手法を実装して、クライアント側でx秒ごとにサーバーにアクセスします。

プッシュ通知アプローチの使用またはnoSqlデータストアの使用を検討している他のソリューションに懸念があります。これは、Djangoフレームワークに組み込まれているツールを使用する従来のプル通知システムよりもはるかに複雑であり、非常にまれな例外を除いて、やり過ぎです。厳密なリアルタイムソリューションが特に必要な場合を除いて、シンプルに保ち、フレームワークにすでに存在するツールを使用します。データベースやネットワークのパフォーマンスに基づいて異議を唱える人にとっては、時期尚早の最適化がすべての悪。

アプリケーションに固有の最近のアクティビティデータを含むモデルを構築します。アプリケーションが新しいアクティビティをログに記録する必要がある場合は、このテーブルに挿入するだけです。

ビューは他のビューと同じようになり、このテーブルから上位x行をプルしRecentActivityます(オプションでクエリパラメータなどに基づきます)。

次に、クライアント側では、単純なajaxポーラーがx秒ごとにビューをヒットするだけです。使用できる複雑なプラグインやテクノロジーに不足はありませんが、独自に作成することもそれほど複雑ではありません。

function simplePoll() {
  $.get("your-url", {query-parameters}, function(data){
    //do stuff with the data, replacing a div or updating json or whatever
    setTimeout(simplePoll, delay);
  });
}

私の意見では、パフォーマンスの問題は、サイトが問題になるほど成功するまでは実際には問題ではありません。従来のリレーショナルデータベースは、TwitterやGoogleなどの成功のレベルに到達し始めるまで、かなりうまくスケールアップできます。私たちのほとんどは、そのレベルではありません:)

于 2011-10-02T19:08:22.327 に答える
2

Signalsの使用を検討しましたか?最近のactivity_post_save()でシグナルを送信し、情報をキャッシュに保存するリスナーが存在する可能性があります。

ビューはキャッシュを参照して、新しい通知があるかどうかを確認します。もちろん、Signalsは必要ありませんが、「通知ハンドラー」を追加できるので、IMHOの方が少しすっきりします。

DBをポーリングする必要がないため(人工的なロード)、これは最適のようです。通知はほぼ即座に「表示」されます(シグナルの処理とキャッシュの操作に必要な時間の後でのみ)。

したがって、擬似コードは次のようになります。

# model
def recent_activity_post_save():
    post_save_signal.send()

# listener
def my_handler( ... ):
    cache.set( 'notification', .... )

post_save_signal.connect( my_handler )

# view
def my_view( request ):
    new_notification = None
    while not new_notification:
        sleep(1)
        new_notification = cache.get( 'notification' )
    return HttpResponse(...)
于 2011-09-28T14:08:55.083 に答える
1

Apeプロジェクトのようなコメットソリューションを使用できます。この種のプロジェクトは、リアルタイムのデータをブラウザに送信するように設計されており、最新のブラウザのWebソケット機能を利用できます。

于 2011-09-18T08:28:28.540 に答える
0

コメットソリューションをお探しの場合は、を使用できますorbitedorbitedただし、これはかなりニッチなソリューションであるため、本番環境での展開と使用方法に関する適切なドキュメントを見つけるのは非常に難しいことを警告しておきます。

于 2011-09-26T23:57:18.047 に答える
0

本当に必要でない場合は、ロングポーリングの使用に制限する必要はないと思います。可能な限り最良のオプションを利用するように作成されたライブラリがあります(以前のオプションが利用できない場合は、短いポーリング、長いポーリング、WebSocket、または小さなフラッシュプラグインである可能性があります)。Node.jsには、Socket.IOと呼ばれる、このようなジョブに最適なライブラリの1つがありますが、幸運なことに、gevent-socketiotornadioの2つのPython実装も利用できますが、後でtornadoフレームワークの上に構築されるため、おそらく質問の。

それが適切な場合は、それらをいくつかのNoSQL(ドキュメント)データベースと組み合わせることができます。これは、リレーショナルデータベースよりもはるかに高速で軽量であることが証明されています。CouchDB、MongoDB、Redisなど、多くのオプションがあります。Socket.IOとドキュメントベースのDBの組み合わせは、高速、軽量、信頼性が高いことが証明されています。

コメントですでにNoSQLを検討しているのを見てきましたが、個人的な意見としては、迅速で簡単なソリューションが必要であり、上記のオプションが適している場合は、これが最善のチャンスです。

于 2011-10-02T17:50:16.923 に答える
0

トリガーを使用できます(新しい投稿が作成されるたびに発生します)。このトリガーは、たとえば、必要なデータ(主キーなど)を含む新しいファイルをポーリングディレクトリに書き込むことができます。Pythonは、新しいファイルが表示されるまでデータベースにアクセスしなくても、そのフォルダーで新しいファイルが作成されるのを監視できます。

于 2011-09-18T08:18:54.693 に答える
0

これも同様の議論であり、サーバー側の観点から答えています。WebSocketとpython / django(/ twined?)を使用して移動 を行う場合、最も重要な答えはこれです。

この答えもあり、Djangoからこれを試みる代わりに非常に堅実に見える代替案を示しています。

これを既存のDjangoアプリケーションから本当に提供したい場合は、このサーバー側を実行しないでください。そのHTTPソケットを単一のブラウザの接続に人質にすることは、アプリケーションを破壊するための迅速な方法です。2つの合理的な代替手段は次のとおりです。さまざまなWebソケットオプション(Pyramidを使用してサービスをホストする上記のオプションなど)を調べるか、ブラウザーが定期的にポーリング要求をサーバーに送信して更新を探すようにします。

于 2011-09-27T02:52:24.653 に答える
0

メッセージの配信に「プル」アーキテクチャと「プッシュ」アーキテクチャのどちらを使用するかを決定する必要があります。クォーラに関するこの投稿を参照してください。受信者に通知を「プッシュ」するソリューションを探している場合は、多くの書き込みアクションでそれほど高い負荷が発生しないため、キャッシング/nosqlベースのシステムが適しています。

たとえば、ソートされたセット/リストデータ構造を持つRedisは、多くのインスタンスを提供します。たとえばを参照してください。この投稿(Pythonではありませんが)はアイデアを得るためのものです。たとえば、 RabbitMQのような「実際の」メッセージキューを調べることもできます。

クライアント接続については、ここにある他の投稿で、ツイストフレームワークや同様のフレームワークの使用方法に関するアイデアがすでに得られているはずです。

そして、Celeryは常に優れたツールになる可能性があります。非同期ジョブでユーザーのアクティビティストリームへのすべての書き込みを行います。

于 2011-09-30T21:23:38.823 に答える