我有一个不寻常的问题,我设法找到了根。 我目前正在建立 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文件。
答案 0 :(得分:3)
最好的选择是使用flock()
来锁定您的文件以进行编写 - http://ar2.php.net/flock - 使用循环来实现Windows兼容性,因为flock
没有阻止选项(在您的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
或memcached
来存储锁,然后可以从其他PHP进程检查。假设你有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);
}
答案 1 :(得分:1)
请考虑使用Apc
apc_store('refresh', time());
存储
apc_get('refresh');
要撤退
yum install php-apc
此外,您甚至不必将时间存入其中
你可以存放一个柜台
apc_inc('refresher');
存储
每次发生变化时都会增加
并检查js是否新值高于您之前的值。