php+redis实现全页缓存系统
php redis 实现全页缓存系统
之前的一个项目说的一个功能,需要在后台预先存入某个页面信息放到数据库,比如app的注册协议,用户协议,这种.然后在写成一个php页面,app在调用接口的时候访问这个页面.当时我就发现一个问题,这些协议往往几个月才会修改一次,而每一次用户查看这些协议的时候,nginx都会重新从数据库读取文件,速度会很慢慢了.
如下图m_about.php是我生成的数据页,
在虚拟机环境下从数据库加载出来重新生成文件需要2.4s(当然实际的测试环境会快一点).
既然这种页面数据都是更新少,为什么不缓存起来呢,想到之前看的redis常用应用里面有一个全页缓存系统(full page cache).不如写一个试试看.
代码思路
redis使用的是phpredis扩展,当然你也可是用predis扩展,只不过需要更改里面几个读取函数而已.
关于缓存系统的接口,我这里参考了laravel里面cache系统.这个系统的设计接口我觉得设置的很清晰,里面不只是包含redis,还可以使用文件,mysql,memcache.
当然全页缓存用不到那么多东西.只是借用他的函数设计.首先是函数getUrlText,这个是获取全页面的数据,这里没有想到太多,直接使用file_get_contents,当然你也可以改写成curl函数
/** * 获取对应的url的信息 * @param string $url 对应的地址 * @return boolean|string */ public function getUrlText($url) { if (empty($url)) { return false; } return file_get_contents($url); }
其次是几个借鉴cache系统的函数,remember函数,记忆缓存,这个是对外的最重要的接口,一般在缓存系统里面直接使用它就好.
/** * 记录对应的缓存,如果之前存在则返回原本的缓存 * @param string $cacheName 缓存名 * @param string | callback $urlOrCallback 需要缓存的数据地址.可以是一个 网页地址也一个可回调类型,如果不是可回调类型,则判定是一个网址 * @param null | int $ttl 缓存过期时间,如果不过期就是用默认值null * @throws \Exception 如果无法访问地址 * @return boolean|string 缓存成功返回获取到的页面地址 */ public function remember($cacheName, $urlOrCallback, $ttl = null) { $value = $this->get($cacheName);//检查缓存是否存在 if (!$value) { //之前没有使用键 if (is_callable($urlOrCallback)) { $text = $urlOrCallback(); } else { //如果不是回调类型,则尝试读取网址 $text = $this->getUrlText($urlOrCallback); } if (empty($text)) { throw new \Exception('can not get value:' . $urlOrCallback); } $this->put($cacheName, $text, $ttl); return $text; } else { return $value; } }
refresh函数,刷新缓存函数,如果缓存页面被更新了,就去刷新它.
/**
* 更新缓存,并返回当前的缓存
* @param string $cacheName 缓存名
* @param string | callback $urlOrCallback 需要缓存的数据地址.可以是一个 网页地址也一个可回调类型,如果不是可回调类型,则判定是一个网址
* @param null | int $ttl 过期时间,如果不过期就是用默认值null
* @return boolean|string 缓存成功返回获取到的页面地址
*/
public function refresh($cacheName, $urlOrCallback, $ttl = null)
{
$this->delete($cacheName);
return $this->remember($cacheName, $urlOrCallback, $ttl);
}
剩下的两个代码文件.一个是redisFPC.php,这是全页缓存的demo,一个是测试用的文件
fpcTest.php
这里是用的是github,连接到我本人的git博客上面.如果连接github有问题,可以看本文最后给的完整代码.
测试
我们在这里测试,第一次加载因为需要读取对应的m_ahout的信息,所以慢一点
第二次加载因为从redislimian 读取了,所以会快的多
使用建议
代码我认为已经给了足够多的接口了,在第一次缓存的时候使用remember函数记录缓存,之后如果缓存变化后使用refresh函数,更新缓存即可.如果可能的话,尽量使用ttl设置缓存的过期时间.
完整代码
redisFPC.php
namespace RedisFPC;class RedisFPC{ /** * php redis的访问类 * @var unknown */ private $redis; /** * 构造函数 * @param array $redis 使用phpredis的类 * @param 是否连接成功 */ public function __construct($redis = []) { //$this->redis = $redis; $this->redis = new \Redis(); return $this->redis->connect('127.0.0.1'); } /** * 记录对应的缓存,如果之前存在则返回原本的缓存 * @param string $cacheName 缓存名 * @param string | callback $urlOrCallback 需要缓存的数据地址.可以是一个 网页地址也一个可回调类型,如果不是可回调类型,则判定是一个网址 * @param null | int $ttl 缓存过期时间,如果不过期就是用默认值null * @throws \Exception 如果无法访问地址 * @return boolean|string 缓存成功返回获取到的页面地址 */ public function remember($cacheName, $urlOrCallback, $ttl = null) { $value = $this->get($cacheName);//检查缓存是否存在 if (!$value) { //之前没有使用键 if (is_callable($urlOrCallback)) { $text = $urlOrCallback(); } else { //如果不是回调类型,则尝试读取网址 $text = $this->getUrlText($urlOrCallback); } if (empty($text)) { throw new \Exception('can not get value:' . $urlOrCallback); } $this->put($cacheName, $text, $ttl); return $text; } else { return $value; } } /** * 获取对应的缓存值 * @param string $cacheName 缓存名 * @return String | Bool,如果不存在返回false,否则返回对应的缓存页信息 */ public function get($cacheName) { return $this->redis->get($this->getKey($cacheName)); } /** * 将对应的全页缓存保存到对应redis中 * @param string $cacheName 缓存名 * @param string $value * @param null | int $ttl 过期时间,如果不过期就是用默认值null * @return boolean 保存成功返回true */ public function put($cacheName, $value, $ttl = null) { if (is_null($ttl)) { return $this->redis->set($this->getKey($cacheName), $value); } else { return $this->redis->set($this->getKey($cacheName), $value, $ttl); } } /** * 删除对应缓存 * @param string $cacheName 缓存名 */ public function delete($cacheName) { return $this->redis->delete($this->getKey($cacheName)); } /** * 更新缓存,并返回当前的缓存 * @param string $cacheName 缓存名 * @param string | callback $urlOrCallback 需要缓存的数据地址.可以是一个 网页地址也一个可回调类型,如果不是可回调类型,则判定是一个网址 * @param null | int $ttl 过期时间,如果不过期就是用默认值null * @return boolean|string 缓存成功返回获取到的页面地址 */ public function refresh($cacheName, $urlOrCallback, $ttl = null) { $this->delete($cacheName); return $this->remember($cacheName, $urlOrCallback, $ttl); } /** * 获取对应的url的信息 * @param string $url 对应的地址 * @return boolean|string */ public function getUrlText($url) { if (empty($url)) { return false; } return file_get_contents($url); } /** * 生成全页缓存键名 * @param string $cacheName 需要缓存的名称 * @return string 对应的在redis中的键名 */ private function getKey($cacheName) { return 'FPC:'. $cacheName; }}
测试用的test代码
注意这里的url写的是本地的缓存url
use RedisFPC\RedisFPC; require_once 'redisFPC.php';/* $text = file_get_contents('http://localhost:1002/m_about.php');var_dump($text); */$url = 'http://localhost:1002/m_about.php'; $fpc = new RedisFPC();echo $fpc->remember('服务协议', $url, 60*60*24);
以上就是php+redis实现全页缓存系统的详细内容,更多请关注php中文网其它相关文章!
---------------------
来源地址:https://www.php.cn/php-weizijiaocheng-459964.html
php+redis实现全页缓存系统的更多相关文章
- 全页缓存FPC?
除基本的会话 token 之外,Redis 还提供很简便的 FPC 平台.回到一致性问题, 即使重启了 Redis 实例,因为有磁盘的持久化,用户也不会看到页面加载速度的 下降,这是一个极大改进,类似 ...
- magento 全页缓存
全页缓存能极大的提高网页的响应速率,但magento社区的商用全页缓存工具都很贵,但是有一款免费的叫ezzoom,虽然免费但是功能强大,能够对产品.分类.特定模块进行缓存,还支持页面某些部分的动态加载 ...
- Memcache,Redis,MongoDB(数据缓存系统)方案对比与分析
mongodb和memcached不是一个范畴内的东西.mongodb是文档型的非关系型数据库,其优势在于查询功能比较强大,能存储海量数据.mongodb和memcached不存在谁替换谁的问题. 和 ...
- 分布式缓存系统 Memcached 快速入门
Memcached介绍 官网地址 Memcached 是一个高性能的分布式内存对象缓存系统,用于动态Web应用以减轻数据库负载.它通过在内存中缓存数据和对象来减少读取数据库的次数,从而提 ...
- 我们也有自带的缓存系统:PHP的APCu扩展
想必大家都使用过 memcached 或者 redis 这类的缓存系统来做日常的缓存,或者用来抗流量,或者用来保存一些常用的热点数据,其实在小项目中,PHP 也已经为我们准备好了一套简单的缓存系统,完 ...
- nginx+redis 实现 jsp页面缓存,提升系统吞吐率
最近在开发的时候,发现之前APP客户端的一部分页面用的是webview交互,这些页面请求很多,打开一套试卷,将会产生100+的请求量,导致系统性能下降.于是考虑在最靠近客户端的Nginx服务器上做Re ...
- Django缓存系统选择之Memcached与Redis的区别与性能对比
Django支持使用Memcached和Redis这两种流行的内存型数据库作为缓存系统.我们今天来看Memcached和Redis的区别和性能对比. redis和memcached的区别 1.Redi ...
- 缓存系统——redis数据库
缓存系统有:mongodb.redis(速度更快).memcache 学习memcached 参考:http://www.cnblogs.com/wupeiqi/articles/5132791.ht ...
- Redis基础知识之—— 缓存应用场景
转载原文:http://www.cnblogs.com/jinshengzhi/articles/5225718.html 一.MySql+Memcached架构的问题 Memcached采用客户端- ...
随机推荐
- 11.2 uptime:显示系统的运行时间及负载
uptime命令可以输出当前系统时间.系统开机到现在的运行时间.目前有多少用户在线和系统平均负载等信息. [root@cs6 ~]# uptime 17:02:25 up 1:48, 3 user ...
- 写Bug时,需要注意的几点3
在对象之间搬移特性 类往往会因为承担过多责任而变得臃肿不堪. (Move Method)搬移函数 含义:在程序中,里面的一个函数与其类外面的一个类或函数有着紧密的调用或者被调用,则需要对其函数内部的表 ...
- LIN总线多从机与主机通信(控制+反馈)
概念 首先要明确以下两点: LIN 总线通信方式为主从机通信,属于异步通信 "帧头 + 数据帧"才算一完整报文 设计方案 多从机与主机通信数据流(控制+反馈)如下: 一号从机: 第 ...
- DDD划分领域、子域,核心域,支撑域的目的
名词解释 在DDD兴起的原因以及与微服务的关系中曾举了一个研究桃树的例子,如果要研究桃树,将桃树根据器官分成根.茎.叶.花.果实.种子,这每一种器官都可以认为是一个研究领域,而领域又有更加具体的细分, ...
- Java常用集合笔记
最近事情比较少,闲暇之余温习巩固一下Java的一些基础知识,并做一些笔记, Java常用集合, 主要参考的这篇文章:Java常用集合 ArrayList/Vertor 1. ArrayList 的主要 ...
- 搞定Redis(一)Redis的安装和五大基本数据类型
一.Redis概述及安装 1.概述: 1.1.Redis是一个开源的key - value存储系统. 1.2.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串). ...
- Pandas之:Pandas高级教程以铁达尼号真实数据为例
Pandas之:Pandas高级教程以铁达尼号真实数据为例 目录 简介 读写文件 DF的选择 选择列数据 选择行数据 同时选择行和列 使用plots作图 使用现有的列创建新的列 进行统计 DF重组 简 ...
- 支持边云协同终身学习特性,KubeEdge子项目Sedna 0.3.0版本发布!
摘要:随着边缘设备数量指数级增长以及设备性能的提升,边云协同机器学习应运而生,以期打通机器学习的最后一公里. 本文分享自华为云社区<支持边云协同终身学习特性,KubeEdge子项目Sedna 0 ...
- 可视化反投射:坍塌尺寸的概率恢复:ICCV9论文解读
可视化反投射:坍塌尺寸的概率恢复:ICCV9论文解读 Visual Deprojection: Probabilistic Recovery of Collapsed Dimensions 论文链接: ...
- SLAM架构的两篇顶会论文解析
SLAM架构的两篇顶会论文解析 一. 基于superpoint的词袋和图验证的鲁棒闭环检测 标题:Robust Loop Closure Detection Based on Bag of Super ...