首頁  >  文章  >  後端開發  >  php+redis實作全頁快取系統

php+redis實作全頁快取系統

藏色散人
藏色散人轉載
2020-09-11 13:31:435914瀏覽

推薦:《PHP影片教學》《redis教學

php redis 實作全頁快取系統

#之前的一個項目說的一個功能,需要在後台預先存入某個頁面信息放到資料庫,例如app的註冊協議,用戶協議,這種.然後在寫成一個php頁面,app在調用接口的時候訪問這個頁面.當時我就發現一個問題,這些協議往往幾個月才會修改一次,而每一次使用者查看這些協定的時候,nginx都會重新從資料庫讀取檔案,速度會很慢慢了.

如下圖m_about.php是我產生的資料頁,

php+redis實作全頁快取系統

在虛擬機器環境下從資料庫載入出來重新產生檔案需要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的資訊,所以慢一點

php+redis實作全頁快取系統

#第二次載入因為從redislimian 讀取了,所以會快的多
php+redis實作全頁快取系統

使用建議

程式碼我認為已經給了足夠多的介面了,在第一次快取的時候使用remember函數記錄緩存,之後如果快取變化後使用refresh函數,更新快取即可.如果可能的話,盡量使用ttl設定快取的過期時間.

完整程式碼

redisFPC. php

<?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(&#39;127.0.0.1&#39;);
    }
    /**
     * 记录对应的缓存,如果之前存在则返回原本的缓存
     * @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(&#39;can not get value:&#39; . $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 &#39;FPC:&#39;. $cacheName;
    }
}

測試用的test程式碼
注意這裡的url寫的是本地的快取url

<?php 
use RedisFPC\RedisFPC;

require_once &#39;redisFPC.php&#39;;
/* $text = file_get_contents(&#39;http://localhost:1002/m_about.php&#39;);
var_dump($text); */
$url = &#39;http://localhost:1002/m_about.php&#39;;

$fpc = new RedisFPC();
echo $fpc->remember(&#39;服务协议&#39;, $url, 60*60*24);

                   

#############################################################################

以上是php+redis實作全頁快取系統的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:csdn.net。如有侵權,請聯絡admin@php.cn刪除