阅读 1952

使用Nginx+Memcache做页面缓存

前言

官方商城改版之后,为了提升动态页面的访问速度,对商城的一些页面进行了缓存,使其在一定时间之内避免了重复的查询和编译。

原理

主要使用了 nginxmemcached_module 模块,直接从 Memcache 服务器中读取并输出。

如若不存在,则执行相应程序,并将结果写入 Memcahce

结构图

使用Memcached做页面缓存结构图

主要流程是:

用户的请求进来,NginxMemcache 获取数据,如若成功,则直接返回给客服端。如若失败,则 Nginx 会报 not found 错误,这个时候,需要 rewirte 执行相关应用程序,在页面渲染结束后,将结果写入 Memcache 。那么下次请求,将直接从 Memcache 获取。

具体实现

Nginx 的配置

upstream memcacheds {
    server 127.0.0.1:11211;
}
server {
    ... # 这里的配置不变
    location @rewrite {
        rewrite ^/(.*)$ /index.php?/$1 last;
    }
    set $memcached_key 0; # 初始化一下$memcached_key
    location ~ /(articles)  {
        set $memcached_key $host$uri; # 用url作为标识
        add_header X-IMJCW-Key $memcached_key; # 加到header里,方便管理
        default_type text/html;
        memcached_connect_timeout 1s;
        memcached_read_timeout 2s;
        memcached_send_timeout 2s;
        memcached_pass  memcacheds;
        memcached_gzip_flag 2;
        error_page 404 502 504 = @rewrite;
    }
    ... # 这里的配置不变
    location ~ \.php$ {
        ... # 这里的配置不变
        fastcgi_param X-MEMCACHE-KEY $memcached_key; # 设置参数,为程序是否需要缓存页面做判断
        ... # 这里的配置不变
    }
    ... # 这里的配置不变
}
复制代码

PHP代码

<?php
// 初始化一下 HTML,这里就不动态生成了
$html = 'Hello World';
// 因为缓存的是页面,所以判断一下请求方式是否是 GET
// 同时判断 $_SERVER 里是否存在 X-MEMCACHE-KEY,并且不为空
if ($_SERVER['REQUEST_METHOD'] != 'GET' || !isset($_SERVER['X-MEMCACHE-KEY']) || !$_SERVER['X-MEMCACHE-KEY']) {
    echo $html;
    exit();
}
// 获取 X-MEMCACHE-KEY
$memcachedKey = $_SERVER['X-MEMCACHE-KEY'];
// 连接 Memcached
$memcached = new \Memcached();
$memcached->addServer('127.0.0.1', '11211', false);
// 存储
$memcached->set($memcachedKey, $html);
// 留个证据
header('X-IMJCW: miss');
header('X-IMJCW-Key: ' . $xMemcacheKey);
echo $html;
复制代码

示例

Tips: 这里的示例不是由上述代码执行输出的,逻辑是一样的。

第一次访问页面:

第一次访问页面

第二次访问页面:

第二次访问页面

页面输出乱码的问题

在实际应用中,我发现效果并没有我想象的那么美好,主要原因是:页面输出乱码了。

经过多方面查询和向同事的请教,最终得出的结论是:

由于存储到 Memcache 里的数据太大,以至于压缩了一遍后,还是很大,于是又压缩…就这样,输出的时候是压缩后的数据,结果造成了页面乱码的问题。

至于解决方案,有两个:

一、关闭压缩功能

<?php
...
// 获取 X-MEMCACHE-KEY
$memcachedKey = $_SERVER['X-MEMCACHE-KEY'];
// 连接 Memcached
$memcached = new \Memcached();
$memcached->addServer('127.0.0.1', '11211', false);
$memcached->setOption(\Memcached::OPT_COMPRESSION, false);
// 存储
$memcached->set($memcachedKey, $html);
...
复制代码

二、修改 PHP 配置,修改 Memcache 压缩阈值

有则修改,无则添加。

...
[memcached]
memcached.compression_threshold = 1048576
...
复制代码

修改完成以后,需要重启 php-fpm

总结

在配置的过程中还算顺利,只是遇到了一个乱码的问题。也是由于我用的比较简单,所以很多问题并没有暴露出来。不积跬步,无以至千里。加油吧,骚年。

-- EOF --

本文转载自IMJCW

原文链接:使用Nginx+Memcache做页面缓存

关注下面的标签,发现更多相似文章
评论