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 相关文章推荐
基于mysql的论坛(5)
Oct 09 PHP
笑谈配置,使用Smarty技术
Jan 04 PHP
php开发留言板的CRUD(增,删,改,查)操作
Apr 19 PHP
基于PHP常用函数的用法详解
May 10 PHP
php 批量替换程序的具体实现代码
Oct 04 PHP
php中并发读写文件冲突的解决方案
Oct 25 PHP
php实现获取文章内容第一张图片的方法
Nov 04 PHP
thinkPHP实现表单自动验证
Dec 24 PHP
thinkPHP模型初始化实例分析
Dec 03 PHP
php简单计算年龄的方法(周岁与虚岁)
Dec 06 PHP
ThinkPHP5 验证器的具体使用
May 31 PHP
PHP+redis实现的悲观锁机制示例
Jun 12 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
SONY ICF-SW7600的电路分析
2021/03/02 无线电
使用TinyButStrong模板引擎来做WEB开发
2007/03/16 PHP
PHP使用imagick扩展实现合并图像的方法
2017/04/25 PHP
php+ajax实现异步上传文件或图片功能
2017/07/18 PHP
javascript编程起步(第七课)
2007/01/10 Javascript
关于B/S判断浏览器断开的问题讨论
2008/10/29 Javascript
jQuery maxlength文本字数限制插件
2010/04/16 Javascript
Safari5中alert的无限循环BUG
2011/04/07 Javascript
JavaScript实现随机替换图片的方法
2015/04/16 Javascript
高性能JavaScript 重排与重绘(2)
2015/08/11 Javascript
JavaScript sort数组排序方法和自我实现排序方法小结
2016/06/06 Javascript
利用纯Vue.js构建Bootstrap组件
2016/11/03 Javascript
JS常见算法详解
2017/02/28 Javascript
Nuxt v-bind绑定img src不显示的解决
2019/12/05 Javascript
javascript中innerHTML 获取或替换html内容的实现代码
2020/03/17 Javascript
JavaScript 实现下雪特效的示例代码
2020/09/09 Javascript
[01:25]DOTA2超级联赛专访iG 将调整状态找回自己
2013/06/05 DOTA
python append、extend与insert的区别
2016/10/13 Python
python的unittest测试类代码实例
2017/12/07 Python
python微信跳一跳系列之棋子定位颜色识别
2018/02/26 Python
Python 爬虫之Beautiful Soup模块使用指南
2018/07/05 Python
Python基本socket通信控制操作示例
2019/01/30 Python
Python中的Socket 与 ScoketServer 通信及遇到问题解决方法
2019/04/01 Python
深入解析神经网络从原理到实现
2019/07/26 Python
IE矩阵Matrix滤镜旋转与缩放及如何结合transform
2012/11/29 HTML / CSS
日本土著品牌,综合型购物网站:Cecile
2016/08/23 全球购物
体育教育专业自荐信范文
2013/12/20 职场文书
如何写一份好的自荐信
2014/01/02 职场文书
党支部公开承诺书
2014/03/28 职场文书
委托公证书
2014/04/08 职场文书
“向国旗敬礼”主题班会活动设计方案
2014/09/27 职场文书
私用公车造成事故检讨书
2014/11/16 职场文书
pandas:get_dummies()与pd.factorize()的用法及区别说明
2021/05/21 Python
一看就懂的MySQL的聚簇索引及聚簇索引是如何长高的
2021/05/25 MySQL
java设计模式--建造者模式详解
2021/07/21 Java/Android
Java Lambda表达式常用的函数式接口
2022/04/07 Java/Android