我認爲你的要求應該考慮到你的流量來實施。
如果您的流量很低,實施基於鎖的計數器可能不成問題。由於併發訪問同一文件的概率非常低,打開,寫入和關閉文件需要幾個毫秒。
另一種解決方案可能是使用memcached,redis或APC緩存機制,並在密鑰存儲區中保留一個計數器。
如果您正在考慮每秒點擊數百萬次,則無法將其託管在單臺服務器上。最有可能的是它與負載均衡器一起擴展,並託管在不同的地區/服務器中。然後一個命中計數器應該像消息隊列一樣實現非阻塞服務。如果你有興趣瞭解排隊你的命中計數器,你可以閱讀更多的rabbitmq,或activemq
的RabbitMQ和ActiveMQ的支持以下協議等多種協議,你可以找到很多PHP客戶端庫,這些協議進行連接。
很少代碼樣本
使用APC作爲抗衡
<?php
apc_add('counter', 0);
echo apc_inc('counter')
?>
使用了Memcached
<?php
$m = new Memcached();
$m->addServer('localhost', 11211);
$m->add('counter', 0);
$m->increment('counter');
?>
的RabbitMQ和php-amqplib
composer.json
{
"require": {
"videlalvaro/php-amqplib": "2.5.*"
}
}
$ composer.phar install
<?php
require_once __DIR__ . '/vendor/autoload.php';
use PhpAmqpLib\Connection\AMQPStreamConnection;
$connection = new AMQPStreamConnection('localhost', 5672, 'guest', 'guest');
$channel = $connection->channel();
$channel->queue_declare('counter', false, false, false, false);
$callback = function($msg) {
// $msg->body has the content of the message
// counter update implementation goes here
};
$channel->basic_consume('counter', '', false, true, false, false, $callback);
while(count($channel->callbacks)) {
$channel->wait();
}
?>
根據該文檔,羊羣將阻塞,直到該鎖被獲取。爲什麼你建議使用循環(假設一個while循環)? – Kasra
對不起,沒有提到:我通常使用flock()和Option LOCK_NB。這給了我避免死鎖的機會。例如。人們只能嘗試鎖定100次然後放棄。 – maxhb