使用Nginx+Memcache作頁面緩存

前言

官方商城改版以後,爲了提高動態頁面的訪問速度,對商城的一些頁面進行了緩存,使其在必定時間以內避免了重複的查詢和編譯。php

原理

主要使用了 nginxmemcached_module 模塊,直接從 Memcache 服務器中讀取並輸出。html

如若不存在,則執行相應程序,並將結果寫入 Memcahcenginx

結構圖緩存

使用Memcached作頁面緩存結構圖

主要流程是:服務器

用戶的請求進來,NginxMemcache 獲取數據,如若成功,則直接返回給客服端。如若失敗,則 Nginx 會報 not found 錯誤,這個時候,須要 rewirte 執行相關應用程序,在頁面渲染結束後,將結果寫入 Memcache 。那麼下次請求,將直接從 Memcache 獲取。memcached

具體實現

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: 這裏的示例不是由上述代碼執行輸出的,邏輯是同樣的。php-fpm

第一次訪問頁面:url

第一次訪問頁面

第二次訪問頁面:spa

第二次訪問頁面

頁面輸出亂碼的問題

在實際應用中,我發現效果並無我想象的那麼美好,主要緣由是:頁面輸出亂碼了。code

通過多方面查詢和向同事的請教,最終得出的結論是:

因爲存儲到 Memcache 裏的數據太大,以致於壓縮了一遍後,仍是很大,因而又壓縮…就這樣,輸出的時候是壓縮後的數據,結果形成了頁面亂碼的問題。

至於解決方案,有兩個:

1、關閉壓縮功能

<?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);
...
複製代碼

2、修改 PHP 配置,修改 Memcache 壓縮閾值

有則修改,無則添加。

...
[memcached]
memcached.compression_threshold = 1048576
...
複製代碼

修改完成之後,須要重啓 php-fpm

總結

在配置的過程當中還算順利,只是遇到了一個亂碼的問題。也是因爲我用的比較簡單,因此不少問題並無暴露出來。不積跬步,無以致千里。加油吧,騷年。

-- EOF --

本文轉載自IMJCW

原文連接:使用Nginx+Memcache作頁面緩存

相關文章
相關標籤/搜索