欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

使用Nginx+Memcache做页面缓存

程序员文章站 2022-06-19 13:34:10
...

前言

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

原理

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

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

结构图

主要流程是:

用户的请求进来,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做页面缓存