1

実行するデータベース クエリの数を減らすことで、より効率的にしようとしている Web アプリケーションがあります。私はある種のコメット スタイルのソリューションを実装する傾向がありますが、この部門での経験が不足しているため、もっと単純なソリューションが存在するかどうか疑問に思っています。

簡潔にするために、ネットワーク上のシステムのリストとその現在のステータス (稼働中か停止中か) を含むデータベースがあるとします。ユーザーは Web アプリにサインインし、監視するシステムを選択できます。その後、現在ダウンしているシステムの数を表示する監視ページにアクセスできます。

現在、カウントはAjaxを使用して更新されています...毎分、クライアントはサーバーにリクエストを送信し、サーバーはデータベースに対してクエリを実行して現在のカウントを取得し、結果をクライアントに返します。私はこれが非効率であることを知っています。ログインするクライアントごとに、データベースに対して別のクエリが毎分実行されます。O(n) = 悪い!

memcached などの何らかのタイプのキャッシュを使用できることはわかっていますが、それでも毎分すべてのユーザーにリクエストがあることを意味します。より良いですが、それが最善の解決策ではないように感じます。

私は次のようなものを想像しています:

  • サーバーは毎分クエリを実行して、現在ダウンしているすべてのシステムの数を取得します。
  • 次に、サーバーはこのデータを関心のあるクライアントにプッシュします。

そうすれば、ログインして監視ページを見ているユーザーの数に関係なく、サーバーは 1 分間に 1 つのクエリしか実行しません。O(1) = いいね! 問題は、私が行ったすべての調査の後でも、これを実装する方法がよくわからないことです。正直なところ、私が探しているものが何であるかを完全には理解していないため、解決策を調査す​​るのは非常に困難です. ですから、より賢明な開発者が私を正しい方向に導いてくれることを願っています。

4

2 に答える 2

0

コメットでできます。ただし、1分ごとにサーバーをポーリングするJavaScriptタイマーを設定することもできます。それはあなたがどれだけ早くフィードバックを望むかに依存します。TCP接続を常に開いたままにする必要はありません。

また、サーバーのステータスを確認する方法は、クライアントがこの情報を取得する方法とは無関係です。クライアントが要求するたびにサーバーのステータスを更新することは望ましくありません。代わりに、サーバーのステータスをポーリングして保存するタイマーがアプリサーバーにあります。クライアント要求は、実際のライブステータスではなく、この保存されたステータスから供給されます。

于 2012-06-23T21:07:58.743 に答える
0

The solution to this issue can easily be solved with an app called Pusher, which is a hosted publish/subscribe API. In a nut shell, Pusher provides two libraries, one for the client (the subscriber) and one for the server (the publisher).

The publisher can be a single script on your server (there are quite a few languages available) set to run at whatever interval you desire. Each time it runs it will connect to a channel and publish to it whatever data it generates. The client is created via a bit of JavaScript in your web app, and whenever a user navigates to your page, the client subscribes to the same channel your server script is publishing to and receives the data as soon as it becomes available and then can manipulate it however you see fit.

The server:

#!/usr/bin/php
<?php
require('Pusher.php');

$dbh = new PDO("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pass);
foreach($dbh->query('SELECT hostname FROM systems WHERE status = 0') as $row) {
    $systems[] = $row['hostname'];
}
$pusher = new Pusher($pusher_key, $pusher_secret, $pusher_app_id);
$pusher->trigger(
    'my-channel',
    'my-event',
    array('message' => implode('<br />', $systems))
);

The client:

<!DOCTYPE html>
<html>
  <head>
    <title>Pusher Test</title>
    <script src="http://code.jquery.com/jquery.min.js" type="text/javascript"></script>
    <script src="http://js.pusher.com/1.12/pusher.min.js" type="text/javascript"></script>
    <script type="text/javascript">
      var pusher = new Pusher(key);
      var channel = pusher.subscribe('my-channel');
      channel.bind('my-event', function(data) {
        $('#systems').html(data.message);
      });
    </script>
  </head>
  <body>
    <div id="systems"></div>
  </body
</html>

So, in this case regardless of how many clients access the page there is only one database query running, and at each interval all the subscribed clients will be updated with the new data.

There is also an open source server implementation of the Pusher protocol written in Ruby called Slanger.

于 2012-12-07T01:11:28.620 に答える