在路由层面给octobercms加缓存

octobercms 缓存在路由中的使用

安装插件

php artisan plugin:install SerenityNow.Cacheroute 

后台设置

假如有个 blog 列表页面 ,且这个页面只是展示作用,没有和前台交互,这就有必要为这个页面添加为缓存,设为10分钟。

直观的对比一下添加缓存后页面的响应时间

我们知道php 有个 microtime(true)函数,记录的是程序运行到某一时间点所用的时间,因此在octobercms启动前,放置一个,在后置中间件也放置一个,两个之差为程序所运行的时间。 在 bootsrrap/app.php 中

define('OCTOBER_START', microtime(true)); //放置

$app = new October\Rain\Foundation\Application(
    realpath(__DIR__.'/../')
);

然后替换文件


//把以下内容替换文件plugins/serenitynow/cacheroute/classes/RouteCacheMiddleware.php
<?php
namespace SerenityNow\Cacheroute\Classes;

use Illuminate\Http\Request as LaravelRequest;
use SerenityNow\Cacheroute\Models\CacheRoute;
use Closure;

class RouteCacheMiddleware
{
    public function handle(LaravelRequest $request, Closure $next)
    {
        //bail if table does not exist or
        //route not in the list of routes to be cached
        $hasTable = \Schema::hasTable('serenitynow_cacheroute_routes');
        $cacheRow = $this->shouldBeCached($request);
        $ajaxRequest = $request->ajax();

        if (!$hasTable || !$cacheRow || $ajaxRequest) {
            $response=$next($request);
            $response->headers->set('X-Elapsed-Time', microtime(true) - OCTOBER_START);
            return $response;
        }
        return $this->cacheResponse($request, $next, $cacheRow['cache_ttl']);
    }

    /**
     * @param LaravelRequest $request
     * @param Closure $next
     * @param $ttl
     * @return mixed
     */
    protected function cacheResponse(LaravelRequest $request, Closure $next, $ttl)
    {
        $cacheKey = $this->getCacheKey($request->url());

        if (\Cache::has($cacheKey)) {
            return \Response::make($this->getCachedContent($cacheKey, $request, \Cache::get($cacheKey)), 200,['X-Elapsed-Time-Cache'=>microtime(true) - OCTOBER_START]);
        }
        $response = $next($request);
        $response->headers->set('X-Elapsed-Time', microtime(true) - OCTOBER_START);
        \Cache::put($cacheKey, $response->getContent(), $ttl);
        return $response;
    }

    /**
     * add instrumentation to help with debug. Adding ?debug
     * to a cached url will precede the content with "CACHED"
     *
     * @param $cacheKey
     * @param $request
     * @param $content
     * @return string
     */
    protected function getCachedContent($cacheKey, $request, $content)
    {
        $isDebugRequest = $request->exists('debug') || $request->exists('cache-info');
        if ($isDebugRequest) {
            return $content.'
            <div class="cache-notice" style="display: block; position: fixed; width: 50%; background: #fff; padding: 20px 30px 25px; left: 50%; border: 1px solid #aaa; margin-left: calc(-50% / 2); bottom: 10%; z-index: 500; box-shadow: 0 0 20px rgba(0,0,0,0.2); font-size: 16px; font-size: 1.6rem;">
                <div class="title" style="margin: -20px -30px 10px; background: #999; color: #fff; padding: 10px 30px; text-align: center;">CACHED CONTENT</div>
                <span class="cache_key" style="display: inline-block; width: 100%; background: #fff; padding: 10px 10px 10px 0; margin-bottom: -10px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
                    <span class="title" style="float: left; width:45px; color: #000; font-weight: bold; line-height: 30px;">URL: </span>
                    <input readonly class="value" style="float: left; width: calc(100% - 45px); border:1px solid #000; color: red; padding: 5px 7px; height: 30px; background: #eee" type="text" value="'.$request->url().'">
                </span>
                <span class="cache_key" style="display: inline-block; width: 100%; background: #fff; color: red; padding: 10px 10px 10px 0; margin-bottom: -10px; white-space: nowrap; overflow: hidden; text-overflow: ellipsis;">
                    <span class="title" style="float: left; width:45px; color: #000; font-weight: bold; line-height: 30px;">KEY: </span>
                    <input readonly class="value" style="float: left; width: calc(100% - 45px); border:1px solid #000; color: red; padding: 5px 7px; height: 30px; background: #eee" type="text" value="'.$cacheKey.'">
                </span>
                <hr style="border:none;">
                <a href="'.$request->url().'" class="cancel" style="float: left; background: #aaa; color: #fff; padding: 10px 15px; margin-top: 20px; text-decoration: none;">Cancel</a>
                <a href="?cache-clear" class="alert alert-info" style="float: right; background: #1991d1; color: #fff; padding: 10px 15px; margin-top: 20px; text-decoration: none;">Clear this now</a>
            </div>';
        }

        if ($request->exists('cache-clear')) {
            \Cache::forget($cacheKey);
            return \Redirect::to($request->url());
        }
        return $content;
    }

    //generate a cache key based on the url

    /**
     * @param $url
     * @return string
     */
    protected function getCacheKey($url)
    {
        return 'SerenityNow.Cacheroute.' . str_slug($url);
    }

    /**
     * @param $request
     * @return bool
     */
    protected function shouldBeCached($request)
    {
        $cacheRouteRows = \Cache::remember('SerenityNow.Cacheroute.AllCachedRoutes',
            \Config::get('cms.urlCacheTtl'),
            function () {
                return CacheRoute::orderBy('sort_order')->get()->toArray();
            }
        );
        info($request->url());
        foreach ($cacheRouteRows as $cacheRow) {
            if (count($cacheRow) && $request->is($cacheRow['route_pattern'])) {
                return $cacheRow;
            }
        }
        return false;
    }
}

只用观察一下header中的X-Elapsed-TimeX-Elapsed-Time-Cache

  • 其中 X-Elapsed-Time 无缓存的运行时间
  • X-Elapsed-Time-Cache 缓存生效后的运行时间

1 第一次进入页面

可以看到无缓存时的运行时间为

X-Elapsed-Time: 0.39185500144958

2 再刷新一次页面 有缓存时的运行时间为

X-Elapsed-Time-Cache: 0.051207065582275

0.3918/0.0512=7.6 提升了将近8倍 还是挺不错的

一般来说缓存的适用场景是页面静态化,这个方法是在路由的基础上增加缓存的,对于不常变动的页面是个很好的方法。,但对于动态页面来说,在路由层面加缓存,就不适合了,这时可以在数据的基础上加缓存,监听数据的变动,之后去更新缓存

如果您想直观的观看下缓存的效果,可以在链接访问 https://jc91715.top/blog?debug 可以清除下缓存观看页面的执行效果

Posted in octobercms, php, 后端 on Apr 17, 2018

请登录 登录 评论!