1

原因を突き止めることができた異常な問題があります。現在、CentOS Linux 6.3 nginx/1.0.15 PHP バージョン 5.3.18 PHP-FPM 5.3.18-1 にセットアップしています。

誰かが新しいタイム スタンプを更新するためにシャウトを投稿するたびに書き込まれる refresh.txt ファイルがあります。また、JS はこのタイムスタンプの値を 1 秒ごとにチェックします。これの問題は..5人以上の人が同時にrefresh.txtファイルに書き込むと、100%のCPUを使用するとします。タイムスタンプを書くだけ!!

なぜこれをやっているのかわからない..

これが私のphpコードです。

if(!empty($rf_clear))
    $tb_send = "clear";
else
    $tb_send = time();

// Add flatfile check
$tbcheck = "refresh.txt";
    $tbsend = fopen($tbcheck, 'w');
    $tbtime = $tb_send;
fwrite($tbsend, $tbtime);
fclose($tbsend);

JS

talk_jax.open("GET", boardurl+"/talkbox/refresh.txt?nocache="+nocache);

どうすればこれを修正できますか、またはこれを回避できますか? どんな助けでも大歓迎です。

ありがとう。

編集:これに対する解決策はまだありません。リクエストを制限する方法はありますか?または、これをすべて一緒に行うより良い方法はありますか。

私はAPCキャッシュを試しましたが、問題はphpファイルを十分に速く提供していないため、何か間違ったことをしていない限り、叫び声が本当に遅いですか?

apc_store("refresh", time());

JS

talk_jax.open("GET", boardurl+"/talkbox/refresh.php?nocache="+nocache);

データベースも使ってみました。phpファイルを提供するには遅すぎます。

4

2 に答える 2

3

最良のオプションはflock()、書き込み用にファイルをロックするために使用することです-httpflock ://ar2.php.net/flock-ブロッキングオプションがないため、Windows互換性のためのループを使用します(CentOSの場合は無効ですが、無害です) 。

$max_tries = 5; // don't loop forever
$tbcheck = "refresh.txt";
$tbsend = fopen($tbcheck, 'w');
for ($try=0; $try<$max_tries, $try++){
    if (flock($tbsend, LOCK_EX, true)) {  // acquire an exclusive blocking lock
        fwrite($tbsend, $tb_send);  // write to file
        fflush($tbsend);            // flush output before releasing the lock
        flock($tbsend, LOCK_UN);    // release the lock
        break;                      // exit the loop
    }
    usleep(100);                    // sleep for 100ms if we couldn't get a lock
}
fclose($tbsend);

別のオプションは、ロックを使用APCまたは保存することです。これは、他のPHPプロセスからチェックできます。memcachedコードがあるとすると、次memcachedのようになります。

$timeout = 5; // set a cache expiration so a broken process doesn't lock forever
$key = "file_locked";
$max_tries = 5; // don't loop forever
for ($try=0; $try<$max_tries, $try++){
    // check to see if there is a lock
    if (!Memcached::get($key)){
        // not locked, so set a lock before processing
        Memcached::set($key, true, $timeout);

        // write to the file
        $tbcheck = "refresh.txt";
        $tbsend = fopen($tbcheck, 'w');
        $tbtime = $tb_send;
        fwrite($tbsend, $tbtime);
        fclose($tbsend);

        // delete the lock
        Memcached::delete($key);

        // exit the loop
        break;
    }
    // locked, pause for 100ms
    usleep(100);
}
于 2012-10-29T23:43:57.530 に答える
1

代わりに Apc の使用を検討してください。
apc_store('refresh', time());保管する
apc_get('refresh');回収する

yum install php-apc

その上、時間を保存する必要さえありません。 変更があるたびに増加
するカウンター apc_inc('refresher');を保存して、新しい値が以前の値よりも高い場合はjsをチェックインするだけです。

于 2012-10-31T14:10:45.527 に答える