2

私のウェブサイトには基本的なチャットボックスモジュールがあり、3秒ごとにJquery Ajax呼び出しと、新しいメッセージを送信するための別のjquery呼び出しでチャットボックスを更新しています。特別なことは何もありません。通常、各jqueryajaxリクエストはわずか0.2秒かかります。しかし、20人以上が接続されているサーバーでは、サーバーのCPUが非常に高くなり、各ajaxリクエストに12〜14秒かかり始めます。これは受け入れられません。また、各httpdプロセスは3%〜4%のCPUを消費します。

チャットボックスコードを更新します。

updatechatbox = $.getJSON("/chat/update",{ lastid: $("#messageBox li:last-child").attr("id") }, function(json) {
    $.each(json, function(key, val) {
        var m = val['message'];
        var id = val['id'];
        var messagebox = $("#messageBox ul");
        messagebox.append("<li id="+id+"><span class='msg'>"+m+"</span></li>");

        var myDiv = $("#messageBox");
        myDiv.animate({ scrollTop: myDiv.prop("scrollHeight") - myDiv.height() }, 0);
    });
});

サーバーはFedora15であり、次の構成でWebサービスのプロキシおよびApacheとしてnginxを実行しています。


Timeout 120
KeepAlive On
MaxKeepAliveRequests 100
KeepAliveTimeout 15

IfModule prefork.c
  StartServers       8
  MinSpareServers    5
  MaxSpareServers   20
  ServerLimit      256
  MaxClients       256
  MaxRequestsPerChild  400
IfModule

IfModule worker.c
  StartServers         2
  MaxClients         150
  MinSpareThreads     25
  MaxSpareThreads     75
  ThreadsPerChild     25
  MaxRequestsPerChild  0
IfModule

質問:
-httpdプロセスごとにそれだけのCPUを使用するApacheは正常ですか?
-どうすればこれを修正できますか?

PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
20089 apache    20   0 57524  16m 5840 S  7.3  0.8   0:18.16 httpd
19715 apache    20   0 56828  16m 5852 S  6.6  0.8   0:21.58 httpd
19749 apache    20   0 58536  16m 5864 S  6.6  0.8   0:22.29 httpd
19732 apache    20   0 62880  21m 5856 S  5.6  1.0   0:19.14 httpd
19803 apache    20   0 62076  21m 5840 S  5.3  1.1   0:17.94 httpd
19821 apache    20   0 61856  21m 5828 S  5.0  1.0   0:17.81 httpd
21574 apache    20   0 61584  18m 4664 S  3.3  0.9   0:00.69 httpd
19772 apache    20   0 61856  21m 5864 S  2.6  1.1   0:18.53 httpd
19932 apache    20   0 61856  20m 5844 S  2.6  1.0   0:17.07 httpd
14307 mysql     20   0  306m  52m 4576 S  2.3  2.6  81:32.57 mysqld
13175 nginx     20   0 15532 2284 1032 S  0.3  0.1   0:04.61 nginx

編集:私のPHP更新関数。ZendFrameworkv1.11.11の使用

public function updateAction()
{
    $auth = Zend_Auth::getInstance();
    $user_info = $auth->getStorage()->read();
    $adminsess = new Zend_Session_Namespace("admin");
    $referrer = $_SERVER['HTTP_REFERER'];

    $user_id = $user_info->id;

    $query = "SELECT m.id, m.message, m.user_id
              FROM messagebox m
              LEFT JOIN users u ON m.user_id = u.id";

    if(isset($_GET['lastid']) && $_GET['lastid'] != ""){
        $lastId = $_GET['lastid'];
        $query .= "WHERE m.id > $lastId";
    }

    $r = $db->query($query);
    $result = $r->fetchAll();

    $data = array();

    if(count($result) > 0) {
        foreach($result as $row) {
            $data[$row['id']]['id'] = $row['id'];
            $data[$row['id']]['message'] = $row['message'];
            $data[$row['id']]['user_id'] = $user_id;
        }
    }

    echo json_encode($data);
    $this->_helper->layout->disableLayout();
}
4

1 に答える 1

2

私は以前に同様の問題を抱えていましたが、それはセッションのロックに関係していることが判明しました。セッションを開始するPHPスクリプトによってセッションが開かれると、このセッションファイルはロックされます。これは、たとえばAjaxを介してコンテンツをロードするためにWebページがPHPスクリプトに多数の要求を行う場合、各要求がセッションをロックし、他の要求が完了しない可能性があることを意味します。これについては、ここで詳しく説明します。

したがって、次のことを行う必要があります。

session_write_close();

これが原因チェックでない場合は、大きなSQLが多くの再帰を呼び出すなど、計算量の多い作業を行っていません。

于 2012-06-22T16:04:54.807 に答える