对于http请求,我们通常是如何实现访问计数呢?
因为用户的每次请求都是独立的,所以server端计数一般通过session或第三方组件实现,如db或redis之类的!
php常驻内存后,计数功能是不是可以直接内存计数呢?
php常驻内存我们,是通过扩展swoole来实现,下面是一个简单的http服务
http server
$i=0; $http = new SwooleHttpServer("127.0.0.1", 9501); $http->on("start", function ($server) { echo "Swoole http server is started at http://127.0.0.1:9501"; }); $http->on("request", function ($request, $response) use ($i) { $i++; echo "访问次数:$i"; $response->header("Content-Type", "text/plain"); $response->end("Hello World"); }); $http->start();
使用 curl localhost:9501 来访问测试
结果
访问次数:1访问次数:1访问次数:1
次数并没有增加?
改为静态变量 ,static $i = 0;
结果依旧
访问次数:1访问次数:1访问次数:1
仍然不能实现我们要的目的
这是为什么呢,想知道原因,我们先了解一下swoole的工作机制,如图:
然后把进程ID打印出来
<?phpecho "main pid is ". getmypid(). ""; //高性能HTTP服务器 $http = new SwooleHttpServer("127.0.0.1", 9501); $http->on("start", function ($server) { echo "Swoole http server is started at http://127.0.0.1:9501"; }); $http->on("request", function ($request, $response) { echo "worker pid is ". getmypid(). ""; $i++; echo "访问次数:$i"; $response->header("Content-Type", "text/plain"); $response->end("Hello World"); }); $http->start();?>
运行结果
main pid is 122278Swoole http server is started at http://127.0.0.1:9501worker pid is 122281访问次数:1
查看一下系统进程
可以看到,我们定义的$i是在master进程,而$i++是在worker进程,所以每次回调request的$i总是0.
明白了swoole运行机制,我们把代码这样修改
$http->on("request", function ($request, $response) { static $i; echo "worker pid is ". getmypid(). ""; $i++; echo "访问次数:$i"; $response->header("Content-Type", "text/plain"); $response->end("Hello World"); });
这次的运行结果:
worker pid is 122593访问次数:1worker pid is 122593访问次数:2worker pid is 122593访问次数:3worker pid is 122593访问次数:4
可以正常计数了。
这是单进程内的计数,那么 多进程内 、集群又该怎么办呢,可能又要回到传统的方法了!
欢迎同行拍砖交流