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 相关文章推荐
从零开始 教你如何搭建Discuz!4.1论坛
Jul 07 PHP
PHP number_format() 函数定义和用法
Jun 01 PHP
MyEclipse常用配置图文教程
Sep 11 PHP
PHP如何实现Unicode和Utf-8编码相互转换
Jul 29 PHP
适合PHP初学者阅读的4本经典书籍
Sep 23 PHP
利用PHP获取网站访客的所在地位置
Jan 18 PHP
PHP在弹框中获取foreach中遍历的id值并传递给地址栏
Jun 13 PHP
针对thinkPHP5框架存储过程bug重写的存储过程扩展类完整实例
Jun 16 PHP
PHP设计模式之观察者模式定义与用法示例
Aug 04 PHP
php使用QueryList轻松采集js动态渲染页面方法
Sep 11 PHP
thinkphp5引入公共部分header、footer的方法详解
Sep 14 PHP
php输出反斜杠的实例方法
Sep 19 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
FCKeditor的安装(PHP)
2007/01/13 PHP
Zend的MVC机制使用分析(二)
2013/05/02 PHP
深入解析php中的foreach函数
2013/08/31 PHP
destoon复制新模块的方法
2014/06/21 PHP
javascript 打开页面window.location和window.open的区别
2010/03/17 Javascript
jQuery 1.5 源码解读 面向中高阶JSER
2011/04/05 Javascript
利用jQuery操作对象数组的实现代码
2011/04/27 Javascript
Array.prototype.concat不是通用方法反驳[译]
2012/09/20 Javascript
js/jQuery对象互转(快速操作dom元素)
2013/02/04 Javascript
jquery插件实现鼠标经过图片右侧显示大图的效果(类似淘宝)
2013/02/04 Javascript
利用js实现禁止复制文本信息
2015/06/03 Javascript
js+CSS实现模拟华丽的select控件下拉菜单效果
2015/09/01 Javascript
jQuery结合CSS制作动态的下拉菜单
2015/10/27 Javascript
解决jQuery使用JSONP时产生的错误
2015/12/02 Javascript
jQuery实现点击按钮文字变成input框点击保存变成文字
2016/05/09 Javascript
JavaScript编码风格指南(中文版)
2016/08/26 Javascript
js css3实现图片拖拽效果
2017/03/04 Javascript
使用 Vue 实现一个虚拟列表的方法
2019/08/20 Javascript
Vue formData实现图片上传
2019/08/20 Javascript
Vue Extends 扩展选项用法完整实例
2019/09/17 Javascript
微信小程序登录时如何获取input框中的内容
2019/12/04 Javascript
[01:52]2014DOTA2西雅图邀请赛 V社开大会你不知道的小秘密
2014/07/08 DOTA
[44:30]完美世界DOTA2联赛PWL S2 GXR vs Magma 第一场 11.25
2020/11/26 DOTA
python实现自动化报表功能(Oracle/plsql/Excel/多线程)
2019/12/02 Python
keras获得model中某一层的某一个Tensor的输出维度教程
2020/01/24 Python
如何基于python对接钉钉并获取access_token
2020/04/21 Python
基于Python爬虫采集天气网实时信息
2020/06/05 Python
意大利一家专营包包和配饰的网上商店:Borse Last Minute
2019/08/26 全球购物
初中三年毕业生的自我评价分享
2014/02/14 职场文书
十八届三中全会宣传方案
2014/02/21 职场文书
个人课题方案
2014/05/08 职场文书
物理学专业自荐信
2014/06/11 职场文书
反对邪教标语
2014/06/30 职场文书
电影圆明园观后感
2015/06/03 职场文书
钓鱼岛事件感想
2015/08/11 职场文书
从np.random.normal()到正态分布的拟合操作
2021/06/02 Python