我认为您的要求应该考虑到您的流量来实现。
如果您的流量很低,那么实现基于锁的计数器就不是问题。因为并发访问同一个文件的概率非常低,打开、写入和关闭文件需要几毫秒。
另一种解决方案可能是使用 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
作曲家.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();
}
?>