使用 Nginx 和 Memcached 对 WordPress 的整页做缓存

页面加载时间已成为每一个电子商务网站的非常重要的一项指标。而 Magento 是一个资源消耗的大户,如果不使用诸如反向代理和整页缓存机制的话,其性能是非常之差。而使用 nginx + memcached 来创建一个整页缓存是非常简单的。

有言在先:

建议不用使用 Varnish 或者是 Magento 自身的整页缓存机制,本文介绍的方案非常简单,如果你使用其他方法可能会引来更多的麻烦,这些麻烦主要集中在缓存的清除上。

另外一个问题是你需要确认使用指定的 URL 来清除两级缓存中的数据。

下面让我们来看具体的实现方法:

这个配置文件我在 Magento 和 WordPress 都测试过!

001 #memcache servers load balanced
002 upstream memcached {
003         server     server_ip_1:11211 weight=5 max_fails=3  fail_timeout=30s;
004         server     server_ip_2:11211 weight=3 max_fails=3  fail_timeout=30s;
005         server    server_ip_3:11211;
006     keepalive 1024 single;
007 }
008 #fastcgi - little load balancer
009 upstream phpbackend{
010     server     server_ip_1:9000 weight=5 max_fails=5  fail_timeout=30s;
011         server     server_ip_2:9000 weight=3 max_fails=3  fail_timeout=30s;
012         server    server_ip_3:9000;
013 }
014 server {
015     listen   80; ## listen for ipv4; this line is default and implied
016     root /var/www/vhosts/kingletas.com/www;
017     server_name kingletas.com;
018     index index.php index.html index.htm;
019  
020     client_body_timeout  1460;
021     client_header_timeout 1460;
022     send_timeout 1460;
023     client_max_body_size 10m;
024     keepalive_timeout 1300;
025  
026     location /app/                { deny all; }
027     location /includes/           { deny all; }
028     location /lib/                { deny all; }
029     location /media/downloadable/ { deny all; }
030     location /pkginfo/            { deny all; }
031     location /report/config.xml   { deny all; }
032     location /var/                { deny all; }
033  
034    location ~* \.(jpg|png|gif|css|js|swf|flv|ico)$ {
035         expires max;
036         tcp_nodelay off;
037         tcp_nopush on;
038     }
039     location / {
040          
041         try_files $uri $uri/ @handler;
042         expires 30d;
043     }
044    location @handler {
045     rewrite / /index.php;
046     }
047  
048     location ~ \.php$ {
049         if (!-e $request_filename) {
050             rewrite / /index.php last;
051         
052         expires        off; ## Do not cache dynamic content
053         default_type       text/html; charset utf-8;
054         if ($request_method = GET) { # I know if statements are evil but don't know how else to do this
055             set $memcached_key $request_uri; Catalog request modal
056             memcached_pass     memcached;
057             error_page         404 502 = @cache_miss;
058             add_header x-header-memcached true;
059         }
060         if ($request_method != GET) {
061             fastcgi_pass phpbackend;
062         }
063     }
064     location @cache_miss {
065         # are we using a reverse proxy?
066         proxy_set_header  X-Real-IP  $remote_addr;
067         proxy_set_header  X-Forwarded-For $proxy_add_x_forwarded_for;
068         proxy_set_header Host $http_host;
069         proxy_redirect off;
070         proxy_max_temp_file_size 0;
071          
072         #configure fastcgi
073         fastcgi_pass 127.0.0.1:9000;
074         fastcgi_send_timeout  5m;
075         fastcgi_read_timeout 5m;
076         fastcgi_connect_timeout 5m;
077         fastcgi_buffer_size 256k;
078         fastcgi_buffers 4   512k;
079         fastcgi_busy_buffers_size   768k;
080         fastcgi_param GEOIP_COUNTRY_CODE $geoip_country_code;
081         fastcgi_param GEOIP_COUNTRY_NAME $geoip_country_name;
082         fastcgi_param  PHP_VALUE "memory_limit = 32M";
083         fastcgi_param  PHP_VALUE "max_execution_time = 18000";
084         fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
085         include fastcgi_params;
086     }
087     location ~ /\. {
088         deny all;
089     }
090 }
091 #if you want to make it even better your own cdn
092 #server {
093 #      listen 80;
094 #      server_name media.kingletas.com;
095 #      root /var/www/vhosts/kingletas.com/www;
096 #}
097 #server {
098 #      listen 80;
099 #      server_name css.kingletas.com;
100 #      root /var/www/vhosts/kingletas.com/www;
101 #}
102 #server {
103 #      listen 80;
104 #      server_name js.kingletas.com;
105 #      root /var/www/vhosts/kingletas.com/www;
106 #}

另外一个要点需要记住的是 Nginx 试图从内存中读取数据,而不往里面写,也就是说你仍然需要自己负责往 memcached 中写数据,因此我们需要在 WordPress 里的 index.php 做如下处理:

01 /**
02 * Front to the WordPress application. This file doesn't do anything, but loads
03 * wp-blog-header.php which does and tells WordPress to load the theme.
04  *
05 * @package WordPress
06  */
07  
08 /**
09 * Tells WordPress to load the WordPress theme and output it.
10  *
11 * <a href="http://my.oschina.net/var" target="_blank" rel="nofollow">@var</a>  bool
12  */
13 ini_set("memcache.compress_threshold",4294967296); //2^32
14 ob_start();
15  
16 define('WP_USE_THEMES', true);
17  
18 /** Loads the WordPress Environment and Template */
19 require('./wp-blog-header.php');
20  
21 $buffer = ob_get_contents();
22  
23 ob_end_clean();
24  
25 $memcache_obj = memcache_connect("localhost", 11211);
26 memcache_add($memcache_obj,$_SERVER['REQUEST_URI'],$buffer,0);
27  
28 echo $buffer;
   

 

最后需要注意的是,我们必须修改 memcache.compress_threshold 设置项值为很大的数字,因为一旦超限时 memcached 将会忽略不压缩的设置。

同样的思路也适用于 Magento。

英文原文,OSCHINA原创翻译

你可能感兴趣的:(nginx,wordpress,缓存)