【发布时间】:2017-09-27 07:01:34
【问题描述】:
试图弄清楚如何使用 NGINX 和 PHP-FPM 托管 WordPress 网站,但还要添加 Varnish 进行缓存;更糟糕的是,通过 SSL 提供此功能。
我曾与 NGINX、Varnish 和 Gunicorn 合作过一个 SSL Django 站点,我认为这可能是相似的。我之前也设置过 Varnish、Apache 和 WordPress。但到目前为止,我的日志一无所获。
下面是目前的工作原理(NGINX 和 FPM):
NGINX 端口 80 转发到 443(也将 www 转发到非 www)。
server {
listen 80;
listen [::]:80;
server_name example.com www.example.com
return 301 https://example.com$request_uri;
}
NGINX 端口 443 传递给 PHP-FPM 监听端口 9000
server {
listen 443 ssl;
listen [::]:443 ssl;
access_log /var/log/nginx-access.log;
error_log /var/log/nginx-error.log;
server_name example.com;
location / {
try_files $uri $uri/ /index.php?q=$uri&$args;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
fastcgi_pass unix:/var/run/php5-fpm.sock;
fastcgi_index index.php;
include fastcgi_params;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
}
}
所以我添加清漆
我已经在端口 6081(默认)上设置了 Varnish,并将其指向 8080 作为后端。
然后我为 NGINX 添加另一个端口以代理到 FPM(像以前一样)
然后我为 NGINX 添加了这个配置来处理端口 8080,因为它太小了,所以在此处完整发布(注意!这部分似乎是问题):
server {
listen 127.0.0.1:8080;
access_log /var/log/nginx-access.log;
error_log /var/log/php-fpm-error.log;
root /var/www/example.com;
index index.php;
port_in_redirect off;
location / {
try_files $uri $uri/ /index.php?q=$uri&$args;
}
location ~ \.php$ {
try_files $uri =404;
fastcgi_split_path_info ^(.+\.php)(/.+)$;
include fastcgi_params;
fastcgi_index index.php;
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
fastcgi_pass unix:/var/run/php5-fpm.sock;
}
}
然后我将 NGINX 的 SSL 部分更改为 proxy_pass 到 Varnish(就像我在其他项目中所做的那样):
upstream varnish_server {
server 127.0.0.1:6081 fail_timeout=0;
}
server {
listen 443 ssl;
listen [::]:443 ssl;
# etc.
location / {
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header Host $http_host;
proxy_redirect off;
proxy_set_header 'Access-Control-Allow-Origin' '*';
proxy_set_header X-Forwarded-Host $http_host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-Proto https;
proxy_set_header HTTPS "on";
proxy_pass http://varnish_server;
break;
}
}
我收到的错误:
varnishlog 是这样说的:
11 ReqStart c 127.0.0.1 39742 1007025263
11 RxRequest c GET
11 RxURL c /
11 RxProtocol c HTTP/1.0
11 RxHeader c X-Forwarded-For: 12.34.567.890
11 RxHeader c Host: example.com
11 RxHeader c Access-Control-Allow-Origin: *
11 RxHeader c X-Forwarded-Host: example.com
11 RxHeader c X-Real-IP: 12.34.567.890
11 RxHeader c X-Forwarded-Proto: https
11 RxHeader c HTTPS: on
11 VCL_call c pass pass
11 FetchError c no backend connection
11 VCL_call c error deliver
11 VCL_call c deliver deliver
11 TxProtocol c HTTP/1.1
11 TxStatus c 503
11 TxResponse c Service Unavailable
11 TxHeader c Server: Varnish
nginx-error.log 是这样说的:
[error] 7532#0: *1 upstream timed out (110: Connection timed out) while reading response header from upstream, client: 12.34.567.890, server: example.com, request: "GET / HTTP/1.1", upstream: "http://127.0.0.1:6081/", host: "example.com"
从视觉上看,网站挂起大约一两分钟,超时;看不到任何其他错误。
另外,请注意,我按照WordPress Codex 中的建议将其添加到 wp-config.php:
if (strpos($_SERVER['HTTP_X_FORWARDED_PROTO'], 'https') !== false)
$_SERVER['HTTPS']='on';
对此的任何帮助将不胜感激! :D
更新
按要求清漆 default.vcl;不过,它实际上与 tutslpus 教程相同(here):
backend default {
.host = "127.0.0.1";
.port = "8080";
.connect_timeout = 60s;
.max_connections = 500;
}
acl purge {
"127.0.0.1";
"localhost";
}
sub vcl_recv {
set req.grace = 2m;
# Set X-Forwarded-For header for logging in nginx
remove req.http.X-Forwarded-For;
set req.http.X-Forwarded-For = client.ip;
# Remove has_js and CloudFlare/Google Analytics __* cookies and statcounter is_unique
set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(_[_a-z]+|has_js|is_unique)=[^;]*", "");
# Remove a ";" prefix, if present.
set req.http.Cookie = regsub(req.http.Cookie, "^;\s*", "");
# Either the admin pages or the login
if (req.url ~ "/wp-(login|admin|cron)") {
# Don't cache, pass to backend
return (pass);
}
# Remove the wp-settings-1 cookie
set req.http.Cookie = regsuball(req.http.Cookie, "wp-settings-1=[^;]+(; )?", "");
# Remove the wp-settings-time-1 cookie
set req.http.Cookie = regsuball(req.http.Cookie, "wp-settings-time-1=[^;]+(; )?", "");
# Remove the wp test cookie
set req.http.Cookie = regsuball(req.http.Cookie, "wordpress_test_cookie=[^;]+(; )?", "");
# Static content unique to the theme can be cached (so no user uploaded images)
# The reason I don't take the wp-content/uploads is because of cache size on bigger blogs
# that would fill up with all those files getting pushed into cache
if (req.url ~ "wp-content/themes/" && req.url ~ "\.(css|js|png|gif|jp(e)?g)") {
unset req.http.cookie;
}
# Even if no cookies are present, I don't want my "uploads" to be cached due to their potential size
if (req.url ~ "/wp-content/uploads/") {
return (pass);
}
# any pages with captchas need to be excluded
if (req.url ~ "^/contact/" || req.url ~ "^/links/domains-for-sale/") {
return(pass);
}
# Check the cookies for wordpress-specific items
if (req.http.Cookie ~ "wordpress_" || req.http.Cookie ~ "comment_") {
# A wordpress specific cookie has been set
return (pass);
}
# allow PURGE from localhost
if (req.request == "PURGE") {
if (!client.ip ~ purge) {
error 405 "Not allowed.";
}
return (lookup);
}
# Force lookup if the request is a no-cache request from the client
if (req.http.Cache-Control ~ "no-cache") {
return (pass);
}
# Try a cache-lookup
return (lookup);
}
sub vcl_deliver {
if (obj.hits > 0) { # Add debug header to see if it's a HIT/MISS and the number of hits, disable when not needed
set resp.http.X-Cache = "HIT";
} else {
set resp.http.X-Cache = "MISS";
}
# Please note that obj.hits behaviour changed in 4.0, now it counts per objecthead, not per object
# and obj.hits may not be reset in some cases where bans are in use. See bug 1492 for details.
# So take hits with a grain of salt
set resp.http.X-Cache-Hits = obj.hits;
}
sub vcl_fetch {
# set obj.grace = 5m;
set beresp.grace = 2m;
if (req.url !~ "wp-admin|wp-login|product|cart|checkout|my-account|/?remove_item=") {
unset beresp.http.set-cookie;
}
}
和 netstat,按要求:
root@server:/# netstat -tnlp
Active Internet connections (only servers)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.0.1:11211 0.0.0.0:* LISTEN 13454/memcached
tcp 0 0 127.0.0.1:8080 0.0.0.0:* LISTEN 21420/nginx
tcp 0 0 0.0.0.0:80 0.0.0.0:* LISTEN 21420/nginx
tcp 0 0 0.0.0.0:22 0.0.0.0:* LISTEN 3583/sshd
tcp 0 0 127.0.0.1:25 0.0.0.0:* LISTEN 3778/master
tcp 0 0 0.0.0.0:443 0.0.0.0:* LISTEN 21420/nginx
tcp 0 0 0.0.0.0:6081 0.0.0.0:* LISTEN 29149/varnishd
tcp 0 0 127.0.0.1:6082 0.0.0.0:* LISTEN 29148/varnishd
tcp6 0 0 :::3306 :::* LISTEN 3643/mysqld
tcp6 0 0 :::80 :::* LISTEN 21420/nginx
tcp6 0 0 :::22 :::* LISTEN 3583/sshd
tcp6 0 0 ::1:25 :::* LISTEN 3778/master
tcp6 0 0 :::443 :::* LISTEN 21420/nginx
tcp6 0 0 :::6081 :::* LISTEN 29149/varnishd
tcp6 0 0 ::1:6082 :::* LISTEN 29148/varnishd
【问题讨论】:
-
请发布您的 Varnish 配置,this guide 可能会帮助您。请参阅最后的 HTTPS 部分。
-
您看到的错误消息表明 nginx 根本无法连接到 varnish。你能检查清漆是否在线并且正在运行?如果是这样,请粘贴配置,并输出“netstat -tnlp”
-
已更新。回复晚了非常抱歉。我应该说,我看到的错误消息是 Varnish 错误,这意味着 NGINX 实际上是在连接。在我看来,问题是代理回 NGINX,然后是 PHP-FPM。另请注意,我已更改为 PHP-FPM 使用 sock 文件而不是端口 9000(为什么 netstat 不显示 9000)
标签: php wordpress ssl nginx varnish