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 相关文章推荐
PHP实现文件安全下载
Oct 09 PHP
十天学会php之第十天
Oct 09 PHP
PHP初学者头疼问题总结
Oct 09 PHP
第三节--定义一个类
Nov 16 PHP
PHP下一个非常全面获取图象信息的函数
Nov 20 PHP
PHP 正则表达式之正则处理函数小结(preg_match,preg_match_all,preg_replace,preg_split)
Oct 05 PHP
使用php将某个目录下面的所有文件罗列出来的方法详解
Jun 21 PHP
一个PHP的远程图片抓取函数分享
Sep 25 PHP
php switch语句多个值匹配同一代码块应用示例
Jul 29 PHP
支持汉转拼和拼音分词的PHP中文工具类ChineseUtil
Feb 23 PHP
PHP7.1实现的AES与RSA加密操作示例
Jun 15 PHP
laravel 5.3 单用户登录简单实现方法
Oct 14 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求小于1000的所有水仙花数的代码
2012/01/10 PHP
PHP实现获取文件后缀名的几种常用方法
2015/08/08 PHP
PHP+Mysql+jQuery中国地图区域数据统计实例讲解
2015/10/10 PHP
PHP  实现等比压缩图片尺寸和大小实例代码
2016/10/08 PHP
JQuery live函数
2010/12/24 Javascript
使用typeof方法判断undefined类型
2014/09/09 Javascript
详解Javascript 装载和执行
2014/11/17 Javascript
node.js中的buffer.Buffer.isEncoding方法使用说明
2014/12/14 Javascript
jQuery实现拖动调整表格单元格大小的代码实例
2015/01/13 Javascript
理解Javascript的动态语言特性
2015/06/17 Javascript
javascript框架设计之种子模块
2015/06/23 Javascript
JavaScript基本的输出和嵌入式写法教程
2015/10/20 Javascript
jQuery实现Email邮箱地址自动补全功能代码
2015/11/03 Javascript
JavaScript位置与大小(1)之正确理解和运用与尺寸大小相关的DOM属性
2015/12/26 Javascript
AngularJS基础 ng-hide 指令用法及示例代码
2016/08/01 Javascript
JSON与XML的区别对比及案例应用
2016/11/11 Javascript
Bootstrap基本布局实现方法详解
2016/11/25 Javascript
vue 将页面公用的头部组件化的方法
2017/12/18 Javascript
如何检查一个对象是否为空
2019/04/11 Javascript
js实现百度登录窗口拖拽效果
2020/03/19 Javascript
vue页面引入three.js实现3d动画场景操作
2020/08/10 Javascript
vue组件中实现嵌套子组件案例
2020/08/31 Javascript
Python开发编码规范
2006/09/08 Python
Python中replace方法实例分析
2014/08/20 Python
python基础知识小结之集合
2015/11/25 Python
使用python 爬虫抓站的一些技巧总结
2018/01/10 Python
python判断输入日期为第几天的实例
2018/11/13 Python
Python 占位符的使用方法详解
2019/07/10 Python
Win 10下Anaconda虚拟环境的教程
2020/05/18 Python
物流仓管员岗位职责
2013/12/04 职场文书
如何编写优秀的食品项目创业计划书
2014/01/23 职场文书
信息管理应届生求职信
2014/03/07 职场文书
大学生就业自我推荐信
2014/05/10 职场文书
公司户外活动总结
2014/07/04 职场文书
2014年环境卫生工作总结
2014/11/24 职场文书
幼儿园音乐教学反思
2016/02/18 职场文书