PHP基于redis计数器类定义与用法示例


Posted in PHP onFebruary 08, 2018

本文实例讲述了PHP基于redis计数器类定义与用法。分享给大家供大家参考,具体如下:

Redis是一个开源的使用ANSI C语言编写、支持网络、可基于内存亦可持久化的日志型、Key-Value数据库,并提供多种语言的API。

这里使用其incr(自增)get(获取)delete(清除)方法来实现计数器类。

1.Redis计数器类代码及演示实例

RedisCounter.class.php

<?php
/**
 * PHP基于Redis计数器类
 * Date:  2017-10-28
 * Author: fdipzone
 * Version: 1.0
 *
 * Descripton:
 * php基于Redis实现自增计数,主要使用redis的incr方法,并发执行时保证计数自增唯一。
 *
 * Func:
 * public incr  执行自增计数并获取自增后的数值
 * public get   获取当前计数
 * public reset  重置计数
 * private connect 创建redis连接
 */
class RedisCounter{ // class start
  private $_config;
  private $_redis;
  /**
   * 初始化
   * @param Array $config redis连接设定
   */
  public function __construct($config){
    $this->_config = $config;
    $this->_redis = $this->connect();
  }
  /**
   * 执行自增计数并获取自增后的数值
   * @param String $key 保存计数的键值
   * @param Int  $incr 自增数量,默认为1
   * @return Int
   */
  public function incr($key, $incr=1){
    return intval($this->_redis->incr($key, $incr));
  }
  /**
   * 获取当前计数
   * @param String $key 保存计数的健值
   * @return Int
   */
  public function get($key){
    return intval($this->_redis->get($key));
  }
  /**
   * 重置计数
   * @param String $key 保存计数的健值
   * @return Int
   */
  public function reset($key){
    return $this->_redis->delete($key);
  }
  /**
   * 创建redis连接
   * @return Link
   */
  private function connect(){
    try{
      $redis = new Redis();
      $redis->connect($this->_config['host'],$this->_config['port'],$this->_config['timeout'],$this->_config['reserved'],$this->_config['retry_interval']);
      if(empty($this->_config['auth'])){
        $redis->auth($this->_config['auth']);
      }
      $redis->select($this->_config['index']);
    }catch(RedisException $e){
      throw new Exception($e->getMessage());
      return false;
    }
    return $redis;
  }
} // class end
?>

demo.php

<?php
Require 'RedisCounter.class.php';
// redis连接设定
$config = array(
  'host' => 'localhost',
  'port' => 6379,
  'index' => 0,
  'auth' => '',
  'timeout' => 1,
  'reserved' => NULL,
  'retry_interval' => 100,
);
// 创建RedisCounter对象
$oRedisCounter = new RedisCounter($config);
// 定义保存计数的健值
$key = 'mycounter';
// 执行自增计数,获取当前计数,重置计数
echo $oRedisCounter->get($key).PHP_EOL; // 0
echo $oRedisCounter->incr($key).PHP_EOL; // 1
echo $oRedisCounter->incr($key, 10).PHP_EOL; // 11
echo $oRedisCounter->reset($key).PHP_EOL; // 1
echo $oRedisCounter->get($key).PHP_EOL; // 0
?>

输出:

0
1
11
1
0

2.并发调用计数器,检查计数唯一性

测试代码如下:

<?php
Require 'RedisCounter.class.php';
// redis连接设定
$config = array(
  'host' => 'localhost',
  'port' => 6379,
  'index' => 0,
  'auth' => '',
  'timeout' => 1,
  'reserved' => NULL,
  'retry_interval' => 100,
);
// 创建RedisCounter对象
$oRedisCounter = new RedisCounter($config);
// 定义保存计数的健值
$key = 'mytestcounter';
// 执行自增计数并返回自增后的计数,记录入临时文件
file_put_contents('/tmp/mytest_result.log', $oRedisCounter->incr($key).PHP_EOL, FILE_APPEND);
?>

测试并发执行,我们使用ab工具进行测试,设置执行150次,15个并发。

ab -c 15 -n 150 http://localhost/test.php

执行结果:

ab -c 15 -n 150 http://localhost/test.php
This is ApacheBench, Version 2.3 <$Revision: 1554214 $>
Copyright 1996 Adam Twiss, Zeus Technology Ltd, http://www.zeustech.net/
Licensed to The Apache Software Foundation, http://www.apache.org/
Benchmarking home.rabbit.km.com (be patient).....done
Server Software:    nginx/1.6.3
Server Hostname:    localhost
Server Port:      80
Document Path:     /test.php
Document Length:    0 bytes
Concurrency Level:   15
Time taken for tests:  0.173 seconds
Complete requests:   150
Failed requests:    0
Total transferred:   24150 bytes
HTML transferred:    0 bytes
Requests per second:  864.86 [#/sec] (mean)
Time per request:    17.344 [ms] (mean)
Time per request:    1.156 [ms] (mean, across all concurrent requests)
Transfer rate:     135.98 [Kbytes/sec] received
Connection Times (ms)
       min mean[+/-sd] median  max
Connect:    0  0  0.2   0    1
Processing:   3  16  3.2   16   23
Waiting:    3  16  3.2   16   23
Total:     4  16  3.1   17   23
Percentage of the requests served within a certain time (ms)
 50%   17
 66%   18
 75%   18
 80%   19
 90%   20
 95%   21
 98%   22
 99%   22
 100%   23 (longest request)

检查计数是否唯一

生成的总计数

wc -l /tmp/mytest_result.log
   150 /tmp/mytest_result.log

生成的唯一计数

sort -u /tmp/mytest_result.log | wc -l
   150

可以看到在并发调用的情况下,生成的计数也保证唯一。

希望本文所述对大家PHP程序设计有所帮助。

PHP 相关文章推荐
PHP4实际应用经验篇(2)
Oct 09 PHP
Apache2 httpd.conf 中文版
Dec 06 PHP
浅析ThinkPHP中的pathinfo模式和URL重写
Jan 06 PHP
thinkphp学习笔记之多表查询
Jul 28 PHP
PHP判断一个字符串是否是回文字符串的方法
Mar 23 PHP
PHP之图片上传类实例代码(加了缩略图)
Jun 30 PHP
PhpStorm terminal无法输入命令的解决方法
Oct 09 PHP
php微信公众号开发(2)百度BAE搭建和数据库使用
Dec 15 PHP
PHP SFTP实现上传下载功能
Jul 26 PHP
PHP单元测试框架PHPUnit用法详解
Jan 23 PHP
php解决约瑟夫环算法实例分析
Sep 30 PHP
PHP中isset、empty的用法与区别示例详解
Nov 05 PHP
php处理抢购类功能的高并发请求
Feb 08 #PHP
php+redis实现商城秒杀功能
Nov 19 #PHP
php+redis消息队列实现抢购功能
Feb 08 #PHP
PHP多线程模拟实现秒杀抢单
Feb 07 #PHP
PHP设计模式之装饰器模式实例详解
Feb 07 #PHP
PHP使用星号替代用户名手机和邮箱的实现代码
Feb 07 #PHP
PHP unlink与rmdir删除目录及目录下所有文件实例代码
Feb 07 #PHP
You might like
PHP 强制性文件下载功能的函数代码(任意文件格式)
2010/05/26 PHP
mac下安装nginx和php
2013/11/04 PHP
自己写了一个php检测文件编码的函数
2014/04/21 PHP
利用php抓取蜘蛛爬虫痕迹的示例代码
2016/09/30 PHP
PHP针对伪静态的注入总结【附asp与Python相关代码】
2017/08/01 PHP
PHP字典树(Trie树)定义与实现方法示例
2017/10/09 PHP
php layui实现前端多图上传实例
2019/07/30 PHP
jQuery实现的图文高亮滚动切换特效实例
2015/08/10 Javascript
jQuery采用连缀写法实现的折叠菜单效果
2015/09/18 Javascript
谈谈target=_new和_blank的不同之处
2016/10/25 Javascript
BootstrapValidator超详细教程(推荐)
2016/12/07 Javascript
JS实现弹出下载对话框及常见文件类型的下载
2017/07/13 Javascript
深入理解angular2启动项目步骤
2017/07/15 Javascript
js is_valid_filename验证文件名的函数
2017/07/19 Javascript
浅谈Webpack多页应用HMR卡住问题
2019/04/24 Javascript
JavaScript常用进制转换及位运算实例解析
2020/10/14 Javascript
[48:21]林俊杰圣堂刺客超神杀戮秀
2014/10/29 DOTA
[02:22]《新闻直播间》2017年08月14日
2017/08/15 DOTA
[51:00]Secret vs VGJ.S 2018国际邀请赛淘汰赛BO3 第一场 8.24
2018/08/25 DOTA
Python 3.x 新特性及10大变化
2015/06/12 Python
Python中条件判断语句的简单使用方法
2015/08/21 Python
浅谈Python基础之I/O模型
2017/05/11 Python
详解Python 数据库的Connection、Cursor两大对象
2018/06/25 Python
Tesserocr库的正确安装方式
2018/10/19 Python
Python 中的参数传递、返回值、浅拷贝、深拷贝
2019/06/25 Python
python实现关闭第三方窗口的方法
2019/06/28 Python
python Pandas库基础分析之时间序列的处理详解
2019/07/13 Python
tensorflow之自定义神经网络层实例
2020/02/07 Python
Python判断字符串是否为空和null方法实例
2020/04/26 Python
Django中和时区相关的安全问题详解
2020/10/12 Python
Pytorch 中的optimizer使用说明
2021/03/03 Python
HTML5 播放 RTSP 视频的实例代码
2019/07/29 HTML / CSS
应用电子技术专业个人求职信
2013/09/21 职场文书
Mysql 如何实现多张无关联表查询数据并分页
2021/06/05 MySQL
python playwright 自动等待和断言详解
2021/11/27 Python
漫改真人电影「萌系男友是燃燃的橘色」公开先导视觉图
2022/03/21 日漫