AMH是业内不错的主机控制面板软件,在8月份的时候,AMH增加了varnish
程序的支持,借助varnish
可以显著提升网站的打开速度。但是AMH默认安装的varnish
并没有一个比较好的配置,也没有清除缓存的动作。不太合理。
那么今天就来实战一下,以wordpress
网站的反代为例,分享一下边缘节点反代+缓存
的实战经验。
程序安装
AMH默认安装时,是自带LNMP环境的,但反代则需要另外安装LNGX反向代理环境。
登录AMH-7.1面板后台之后,在右上角找到软件商店,然后在网站环境管理里面安装LNGX。
然后还需要安装Varnish缓存程序
AMH环境配置
配置LNGX环境
软件安装成功之后,需要增加反向代理的环境,在软件商店找到LNGX,点击管理
添加一个lngx01的环境
配置varnish
这部分没有其他的配置,主要是需要替换varnish的vcl配置文件,可以在下图找到
用以下内容替换
/*-
* Copyright (c) 2006 Verdens Gang AS
* Copyright (c) 2006-2015 Varnish Software AS
* All rights reserved.
*
* Author: Shing Lau <icodex@msn.com>
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* This is the builtin VCL code
*/
# We're using unix sockets, so we need to declare that we're using VCL 4.1
vcl 4.1;
# Import Varnish Standard Module so I can serve custom error pages
import std;
import cookie;
import directors;
acl purger {
"localhost";
"127.0.0.1";
"172.17.0.1";
"10.0.0.0"/8;
}
# Setup the backend
backend backend1 {
.host = "1.1.1.1"; # `改为源站IP地址`
.port = "80"; # `改为源站端口`
.first_byte_timeout = 300s;
.connect_timeout = 5s;
.between_bytes_timeout = 5s;
}
#######################################################################
# Client side
# Regex purging
# Treat the request URL as a regular expression.
sub purge_regex {
ban("obj.http.X-VC-Req-URL ~ " + req.url + " && obj.http.X-VC-Req-Host == " + req.http.host);
}
# Exact purging
# Use the exact request URL (including any query params)
sub purge_exact {
ban("obj.http.X-VC-Req-URL == " + req.url + " && obj.http.X-VC-Req-Host == " + req.http.host);
}
# Page purging (default)
# Use the exact request URL, but ignore any query params
sub purge_page {
set req.url = regsub(req.url, "\?.*$", "");
ban("obj.http.X-VC-Req-URL-Base == " + req.url + " && obj.http.X-VC-Req-Host == " + req.http.host);
}
sub vcl_recv {
if (req.restarts > 0) {
set req.hash_always_miss = true;
}
if (req.http.host ~ "(?i)(.*)") {
set req.backend_hint = backend1;
} else {
return (synth(403, "Hostname not found."));
}
if (req.restarts == 0) {
std.collect(req.http.x-forwarded-for);
if (req.http.x-forwarded-for) {
set req.http.x-forwarded-for = regsub(req.http.x-forwarded-for + ", " + client.ip, "\s*,.*$", "");
} else {
set req.http.x-forwarded-for = client.ip;
}
}
if (req.http.X-Forwarded-Ssl ~ "(?i)on" ||
req.http.Cloudfront-Forwarded-Proto ~ "(?i)https" ||
req.http.X-Forwarded-Proto ~ "(?i)https" ||
req.http.Proto ~ "(?i)ssl"
) {
set req.http.X-Forwarded-Proto = "https";
set req.http.X-Forwarded-Port = "443";
}
#return (pass);
if (req.method == "PRI") {
/* We do not support SPDY or HTTP/2.0 */
return (synth(405, "We do not support SPDY or HTTP/2.0"));
}
if (req.method != "GET" &&
req.method != "HEAD" &&
req.method != "PUT" &&
req.method != "POST" &&
req.method != "TRACE" &&
req.method != "OPTIONS" &&
req.method != "DELETE" &&
req.method != "PATCH") {
/* Non-RFC2616 or CONNECT which is weird. */
return (pipe);
}
# Implementing websocket support (https://www.varnish-cache.org/docs/4.0/users-guide/vcl-example-websockets.html)
if (req.http.upgrade ~ "(?i)websocket") {
return (pipe);
}
# We only deal with GET and HEAD by default
if (req.method != "GET" && req.method != "HEAD") {
/* We only deal with GET and HEAD by default */
set req.http.X-VC-Cacheable = "NO:Request method:" + req.method;
return (pass);
}
# Set initial grace period usage status
set req.http.grace = "none";
set req.hash_ignore_busy = true;
# Normalize the header, remove the port (in case you're testing this on various TCP ports)
set req.http.Host = regsub(req.http.host, ":[0-9]+", "");
# Normalize the query arguments
set req.url = std.querysort(regsub(req.url, "^http[s]?://", ""));
# collect all cookies
std.collect(req.http.Cookie);
if (req.http.Range ~ "bytes=") {
set req.http.x-range = req.http.Range;
}
# Strip hash, server doesn't need it.
if (req.url ~ "\#") {
set req.url = regsub(req.url, "\#.*$", "");
}
# Strip a trailing ? if it exists
if (req.url ~ "\?$") {
set req.url = regsub(req.url, "\?$", "");
}
# remove ?xxx=xxxxx strings from urls so css and js files are cached.
set req.url = regsub(req.url, "\.js\?.*$", ".js");
set req.url = regsub(req.url, "\.css\?.*$", ".css");
set req.url = regsub(req.url, "\?ver=.*$", "");
set req.url = regsub(req.url, "\?replytocom=.*$", "");
if (req.http.Authorization ||
req.http.Authenticate ||
req.http.WWW-Authenticate) {
/* Not cacheable by default */
set req.http.X-VC-Cacheable = "NO:Requested with: Authenticate";
# set req.hash_always_miss = true;
return (pass);
}
# # don't cache logged-in users. you can set users `logged in cookie` name in settings
# if (req.http.Cookie) {
# set req.http.X-VC-Cacheable = "NO:Found logged in cookie";
# # set req.hash_always_miss = true;
# return (pass);
# }
# don't cache XMLHttpRequest
if (req.http.X-Requested-With == "XMLHttpRequest") {
set req.http.X-VC-Cacheable = "NO:Requested with: XMLHttpRequest";
# set req.hash_always_miss = true;
return (pass);
}
if (req.http.Cache-Control && req.http.Cache-Control ~ "(?i)private") {
set req.http.X-VC-Cacheable = "NO:Private Use";
# set req.hash_always_miss = true;
return (pass);
}
if (req.url ~ "^[^?]*\.(?i)(asp|aspx|ashx|php|php4|php5|cgi|pl|perl|jsp|do)(\?.*)?$" || req.url ~ "\?nocache") {
set req.http.X-VC-Cacheable = "NO:Pass through the dynamic request";
# set req.hash_always_miss = true;
return (pass);
}
# don't cache ajax request
if (req.url ~ "^.*/ajax/.*$" || req.url ~ "^.*/ahah/.*$") {
set req.http.X-VC-Cacheable = "NO:Requested with: Ajax";
return (pass);
}
if (req.url ~ "^/admin/" || req.url ~ "/paypal/") {
set req.http.X-VC-Cacheable = "NO:Requested with: manager area";
return (pass);
}
if ( req.url ~ "(?i)(phpmyadmin|status|munin|server-status|nocache|feed|get|ip)" ||
req.url ~ "(?i)(sitemap.xml($|\.gz$))" ) {
set req.http.X-VC-Cacheable = "NO:Pass through the known exclude";
set req.hash_always_miss = true;
return (pass);
}
# don't cache logged-in users. you can set users `logged in cookie` name in settings
if (req.http.Cookie ~ "(?i)(wp-postpass_|wordpress_logged_in_|comment_author)") {
set req.http.X-VC-Cacheable = "NO:Found logged in cookie";
# set req.hash_always_miss = true;
return (pass);
}
# don't cache these special pages
if (req.url ~ "(?i)(nocache|wp-admin|wp-(json|comments-post|login|activate|mail)\.php|bb-admin|server-status|control\.php|bb-login\.php|bb-reset-password\.php|register\.php)") {
set req.http.X-VC-Cacheable = "NO:Special page: " + req.url;
# set req.hash_always_miss = true;
return (pass);
}
# Pass through the WooCommerce dynamic pages
if (req.url ~ "^/(cart|my-account/*|checkout|wc-api/*|addons|logout|lost-password|product/*)") {
set req.http.X-VC-Cacheable = "NO:Pass through the WooCommerce dynamic pages";
# set req.hash_always_miss = true;
return (pass);
}
# Pass through the WooCommerce add to cart
if (req.url ~ "\?add-to-cart=" ) {
set req.http.X-VC-Cacheable = "NO:Pass through the WooCommerce add to cart";
# set req.hash_always_miss = true;
return (pass);
}
# Pass through the WooCommerce API
if (req.url ~ "\?wc-api=" ) {
set req.http.X-VC-Cacheable = "NO:Pass through the WooCommerce API";
# set req.hash_always_miss = true;
return (pass);
}
if (req.url ~ "^[^?]*\.(?i)(xmlrpc.php|wlmanifest.xml)(\?.*)?$") {
# unset cookie only if no http auth
if (!req.http.Authorization) {
unset req.http.Cookie;
}
return (pass);
}
if (req.http.Accept-Encoding) {
# Do no compress compressed files...
if (req.url ~ "^[^?]*\.(?i)(jpg|jpeg|webp|png|gif|bmp|gz|tgz|bz2|tbz|lzma|mp3|ogg|swf|ico)(\?.*)?$") {
# No point in compressing these
unset req.http.Accept-Encoding;
} elsif (req.http.Accept-Encoding ~ "gzip") {
set req.http.Accept-Encoding = "gzip";
} elsif (req.http.Accept-Encoding ~ "deflate" && req.http.user-agent !~ "MSIE") {
set req.http.Accept-Encoding = "deflate";
} else {
# unknown algorithm
unset req.http.Accept-Encoding;
}
}
if (req.url ~ "(\?|&)(gclid|cx|ie|cof|siteurl|zanpid|origin|fbclid|mc_[a-z]+|utm_[a-z]+|_bta_[a-z]+)=") {
set req.url = regsuball(req.url, "(gclid|cx|ie|cof|siteurl|zanpid|origin|fbclid|mc_[a-z]+|utm_[a-z]+|_bta_[a-z]+)=[-_A-z0-9+()%.]+&?", "");
set req.url = regsub(req.url, "[?|&]+$", "");
}
# Remove all cookies for static files
# A valid discussion could be held on this line: do you really need to cache static files that don't cause load? Only if you have memory left.
# Sure, there's disk I/O, but chances are your OS will already have these files in their buffers (thus memory).
# Before you blindly enable this, have a read here: https://ma.ttias.be/stop-caching-static-files/
if (req.method ~ "^(GET|HEAD)$" &&
(req.http.Content-Type ~ "(?i)(octet-stream|audio|video)" ||
req.url ~ "^[^?]*\.(?i)(bmp|css|csv|doc|docx|eot|gif|ico|jpeg|jpg|js|less|pdf|png|ppt|pptx|rtf|svg|svgz|swf|ttf|txt|webp|woff|woff2|xls|xlsx|xml|avi|flac|flv|mka|mkv|mov|mp3|mp4|mpeg|mpg|ogg|ogm|opus|wav|webm|7z|bz2|gz|rar|tar|tgz|tbz|txz|xz|zip)(\?.*)?$")) {
# enable this if you need it
if (req.url ~ "nocache") {
set req.http.X-VC-Cacheable = "NO:Not cacheable, nocache in URL";
return (pass);
}
# unset cookie only if no http auth
if (!req.http.Authorization) {
unset req.http.Cookie;
}
}
# Send Surrogate-Capability headers to announce ESI support to backend
set req.http.Surrogate-Capability = "key=ESI/1.0";
set req.http.X-VC-My-Purge-Key = "";
if (req.method == "PURGE" || req.method == "SOFTPURGE" || req.method == "BAN") {
if (req.http.X-VC-Purge-Key == req.http.X-VC-My-Purge-Key) {
set req.http.X-VC-Purge-Key-Auth = "true";
} else {
set req.http.X-VC-Purge-Key-Auth = "false";
}
if (client.ip !~ purger && req.http.X-VC-Purge-Key-Auth != "true") {
# return (synth(405, "Not allowed from " + client.ip));
}
if (req.http.X-VC-Purge-Method) {
if (req.http.X-VC-Purge-Method ~ "(?i)regex") {
call purge_regex;
} elsif (req.http.X-VC-Purge-Method ~ "(?i)exact") {
call purge_exact;
} else {
call purge_page;
}
} else {
# No X-VC-Purge-Method header was specified.
# Do our best to figure out which one they want.
if (req.url ~ "\.\*" || req.url ~ "^\^" || req.url ~ "\$$" || req.url ~ "\\[.?*+^$|()]") {
call purge_regex;
} elsif (req.url ~ "\?") {
call purge_exact;
} else {
call purge_page;
}
}
if (req.method == "BAN") {
ban("obj.http.X-URL ~ " + req.http.X-Ban);
/* Throw a synthetic page so the request won't go to the backend. */
return(synth(200, "Ban added"));
} else {
# If you got this stage (and didn't error out above), purge the cached result
return (purge);
}
return (synth(200,"Purged " + req.url + " " + req.http.host));
}
unset req.http.X-VC-My-Purge-Key;
# unset Varnish Caching custom headers from client
#unset req.http.X-VC-Cacheable;
#unset req.http.X-VC-Debug;
return (hash);
}
sub vcl_hash {
hash_data(req.url);
if (req.http.x-range ~ "bytes=") {
hash_data(req.http.x-range);
unset req.http.Range;
}
if (req.http.host) {
hash_data(req.http.host);
} else {
hash_data(server.ip);
}
}
sub vcl_backend_response {
set beresp.grace = 3d;
set beresp.http.X-VC-Req-Host = bereq.http.host;
set beresp.http.X-VC-Req-URL = bereq.url;
set beresp.http.X-VC-Req-URL-Base = regsub(bereq.url, "\?.*$", "");
if (bereq.http.x-range ~ "bytes=" && beresp.status == 206) {
set beresp.ttl = 10m;
set beresp.http.CR = beresp.http.content-range;
}
if (beresp.http.Surrogate-Control) {
set beresp.ttl = std.duration(regsub(beresp.http.Surrogate-Control,"^.*max-age=(\d+).*$","\1"), beresp.ttl);
set beresp.grace = std.duration(regsub(beresp.http.Surrogate-Control,"^.*max-age=\d+\+(\d+).*$","\1"),beresp.grace);
}
if (beresp.http.Vary ~ "User-Agent") {
set beresp.http.Vary = regsub(beresp.http.Vary, ",? *User-Agent *", "");
set beresp.http.Vary = regsub(beresp.http.Vary, "^, *", "");
if (beresp.http.Vary == "") {
unset beresp.http.Vary;
}
}
# Varnish determined the object is not cacheable
if (beresp.http.Authorization ||
beresp.http.Authenticate ||
beresp.http.WWW-Authenticate ||
beresp.http.X-Requested-With == "(?i)XMLHttpRequest") {
set beresp.http.X-VC-Cacheable = "NO: Authenticate ";
set beresp.uncacheable = true;
set beresp.http.magicmarker = 1;
# overwrite ttl with X-VC-TTL
set beresp.http.X-VC-TTL = 0;
set beresp.ttl = 0s;
}
if (beresp.http.Pragma ~ "(?i)no-cache" ||
(!beresp.http.Surrogate-Control && beresp.http.Cache-Control ~ "(?i)no-cache|no-store|private")) {
set beresp.http.Smug-Cacheable = "No";
set beresp.http.magicmarker = "1";
}
if (beresp.http.Set-Cookie && beresp.http.Set-Cookie !~ "(?i)(wp-postpass_|wordpress_logged_in_|comment_author|PHPSESSID)") {
set beresp.http.X-VC-Cacheable = "NO: !obj.Set-Cookie";
set beresp.ttl = 0s;
set beresp.http.Smug-Cacheable = "No";
set beresp.http.magicmarker = "1";
set beresp.uncacheable = true;
}
# Pause ESI request and remove Surrogate-Control header
if (beresp.http.Surrogate-Control ~ "ESI/1.0") {
unset beresp.http.Surrogate-Control;
set beresp.do_gunzip = true;
set beresp.do_esi = true;
}
if (beresp.http.Content-Type ~ "text") {
set beresp.do_esi = true;
}
if (beresp.http.Content-Type ~ "text") {
set beresp.do_gzip = true;
}
# cache only successfully responses and 404s that are not marked as private
if (beresp.status != 200 && beresp.status != 404 && beresp.http.Cache-Control ~ "private") {
set beresp.http.X-VC-Cacheable = "NO: Private Use";
set beresp.uncacheable = true;
set beresp.http.magicmarker = 1;
# overwrite ttl with X-VC-TTL
set beresp.http.X-VC-TTL = 0;
set beresp.ttl = 0s;
}
if (beresp.status == 301 || beresp.status == 302) {
set beresp.http.X-VC-Cacheable = "YES: but for 10s - Status : " + beresp.status;
set beresp.http.Location = regsub(beresp.http.Location, ":[0-9]+", "");
unset beresp.http.Server;
# overwrite ttl with X-VC-TTL
set beresp.http.X-VC-TTL = 10;
}
if (beresp.status == 403 || beresp.status == 404) {
set beresp.http.X-VC-Cacheable = "YES: but for 30s - Status : " + beresp.status;
set beresp.grace = 15s;
# overwrite ttl with X-VC-TTL
set beresp.http.X-VC-TTL = 15;
}
if (beresp.status >= 500 && beresp.status < 600 && bereq.retries < 5) {
if (bereq.method != "POST") {
set beresp.http.X-VC-Cacheable = "NO: Status : " + beresp.status;
set beresp.ttl = 0s;
set beresp.grace = 15s;
# return (abandon);
}
}
if (beresp.status >= 200 && beresp.status < 300 && bereq.method ~ "^(GET|HEAD)$") {
if (bereq.url ~ "^[^?]*\.(?i)(bmp|css|csv|doc|docx|eot|gif|ico|jpeg|jpg|js|less|pdf|png|ppt|pptx|rtf|svg|svgz|swf|ttf|txt|webp|woff|woff2|xls|xlsx|xml)(\?.*)?$") {
unset beresp.http.Set-Cookie;
# overwrite ttl with X-VC-TTL
set beresp.http.X-VC-TTL = 24*60*60*7;
}
if (beresp.http.Content-Type ~ "(?i)(html|xml)") {
set beresp.do_gzip = true;
set beresp.do_esi = true;
# overwrite ttl with X-VC-TTL
set beresp.http.X-VC-TTL = 60*60;
} elsif (beresp.http.Content-Type ~ "(?i)(css|javascript)" ||
beresp.http.Content-Type ~ "(?i)application/(x-)?javascript" ||
beresp.http.Content-Type ~ "(?i)application/(x-)?font-ttf" ||
beresp.http.Content-Type ~ "(?i)application/(x-)?font-opentype" ||
beresp.http.Content-Type ~ "(?i)application/font-woff" ||
beresp.http.Content-Type ~ "(?i)application/vnd\.ms-fontobject" ||
beresp.http.Content-Type ~ "(?i)image/svg\+xml") {
set beresp.do_gzip = true;
# overwrite ttl with X-VC-TTL
set beresp.http.X-VC-TTL = 24*60*60*7;
}
# Large static files are delivered directly to the end-user without
# waiting for Varnish to fully read the file first.
# Varnish 4 fully supports Streaming, so use streaming here to avoid locking.
if (beresp.http.Content-Type ~ "(?i)(octet-stream|audio|video)" ||
bereq.url ~ "^[^?]*\.(?i)(avi|flac|flv|mka|mkv|mov|mp3|mp4|mpeg|mpg|ogg|ogm|opus|wav|webm)(\?.*)?$") {
unset beresp.http.Set-Cookie;
# the backend doesn't send a Content-Length header, so only enable it for big objects
set beresp.do_gzip = false; # Don't try to compress it for storage
# Stream large objects, <= 128 MiB
if (std.integer(beresp.http.Content-Length,0) <= 134217728) {
set beresp.do_stream = true; # Check memory usage it'll grow in fetch_chunksize blocks (128k by default) if
# overwrite ttl with X-VC-TTL
set beresp.http.X-VC-TTL = 60*60;
# do not cache files > 128 MiB
} elsif (std.integer(beresp.http.Content-Length,0) > 134217728) {
set beresp.http.X-VC-Cacheable = "NO:Large static files";
set beresp.uncacheable = true;
set beresp.http.magicmarker = 1;
# overwrite ttl with X-VC-TTL
set beresp.http.X-VC-TTL = 0;
set beresp.ttl = 0s;
}
}
}
# Don't cache object as instructed by header bereq.X-VC-Cacheable
if (bereq.http.X-VC-Cacheable ~ "^NO") {
set beresp.http.X-VC-Cacheable = bereq.http.X-VC-Cacheable;
set beresp.uncacheable = true;
# overwrite ttl with X-VC-TTL
set beresp.http.X-VC-TTL = 0;
set beresp.ttl = 0s;
}
# validate if we need to cache it and prevent from setting cookie
if (beresp.ttl > 0s && (bereq.method == "GET" || bereq.method == "HEAD")) {
unset beresp.http.set-cookie;
}
if (beresp.http.X-VC-Enabled ~ "true") {
if (!beresp.http.X-VC-Cacheable) {
set beresp.http.X-VC-Cacheable = "YES: Is cacheable, ttl: " + std.duration(beresp.http.X-VC-TTL + "s", 0s);
}
} elseif (beresp.http.X-VC-Enabled ~ "false") {
if (!beresp.http.X-VC-Cacheable) {
set beresp.http.X-VC-Cacheable = "NO:Disabled";
}
set beresp.http.X-VC-TTL = 0;
}
# All tests passed, therefore item is cacheable
# set beresp.http.X-VC-Cacheable = "YES: Is cacheable, ttl: " + std.duration(beresp.http.X-VC-TTL + "s", 0s);
# overwrite ttl with X-VC-TTL
if (beresp.http.X-VC-TTL) {
set beresp.ttl = std.duration(beresp.http.X-VC-TTL + "s", 0s);
}
# if (!beresp.http.cache-control) {
# set beresp.ttl = 0s;
# set beresp.uncacheable = true;
# }
return (deliver);
}
sub vcl_deliver {
set resp.http.X-Cache-Age = resp.http.Age;
set resp.http.X-Cache-Alive = regsub(obj.ttl, "^(\d+).[0-9]+", "\1");
unset resp.http.Age;
if (resp.http.CR) {
set resp.http.Content-Range = resp.http.CR;
unset resp.http.CR;
}
# From http://varnish-cache.org/wiki/VCLExampleLongerCaching
if (resp.http.magicmarker) {
/* Remove the magic marker */
unset resp.http.magicmarker;
/* By definition we have a fresh object */
set resp.http.Pragma = "no-cache";
set resp.http.Expires = "-1";
set resp.http.Cache-Control = "no-store, no-cache, must-revalidate, max-age=0";
}
unset resp.http.X-VC-Req-Host;
unset resp.http.X-VC-Req-URL;
unset resp.http.X-VC-Req-URL-Base;
if (obj.hits > 0) {
set resp.http.X-VC-Cache = "HIT";
} else {
set resp.http.X-VC-Cache = "MISS";
}
if (req.http.X-VC-Debug ~ "true" || resp.http.X-VC-Debug ~ "true") {
set resp.http.X-VC-Hash = req.http.hash;
if (req.http.X-VC-DebugMessage) {
set resp.http.X-VC-DebugMessage = req.http.X-VC-DebugMessage;
}
} else {
unset resp.http.X-VC-Enabled;
unset resp.http.X-VC-Cache;
unset resp.http.X-VC-Debug;
unset resp.http.X-VC-DebugMessage;
unset resp.http.X-VC-Cacheable;
unset resp.http.X-VC-Purge-Key-Auth;
unset resp.http.X-VC-TTL;
}
# Change some headers
unset resp.http.X-Powered-By;
unset resp.http.Server;
unset resp.http.X-Varnish;
unset resp.http.Via;
unset resp.http.Link;
unset resp.http.X-Frame-Options;
unset resp.http.X-Content-Type-Options;
unset resp.http.X-Xss-Protection;
unset resp.http.Referer-Policy;
unset resp.http.X-Permitted-cross-domain-policies;
unset resp.http.X-Drupal-Cache;
unset resp.http.X-Page-Speed;
unset resp.http.X-AspNet-Version;
unset resp.http.X-Generator;
unset resp.http.X-Via;
if (obj.hits > 0) {
set resp.http.X-Cache-Remote = "HIT";
set resp.http.X-Cache-Hits = obj.hits;
} else {
set resp.http.X-Cache-Remote = "MISS";
}
set resp.http.X-Cache-Lookup = "Lookup From Disktank";
# HTTP headers for all sites
set resp.http.X-Are-Dinosaurs-Awesome = "HELL YES";
set resp.http.X-Hack = "don't hack me bro";
return (deliver);
}
sub vcl_backend_fetch {
if (bereq.method == "GET") {
unset bereq.body;
}
std.collect(bereq.http.x-forwarded-for);
if (bereq.http.x-range) {
set bereq.http.Range = bereq.http.x-range;
}
if (bereq.http.x-forwarded-for) {
set bereq.http.x-forwarded-for = regsub(bereq.http.x-forwarded-for + ", " + client.ip, "\s*,.*$", "");
} else {
set bereq.http.x-forwarded-for = client.ip;
}
return (fetch);
}
sub vcl_purge {
# Only handle actual PURGE HTTP methods, everything else is discarded
if (req.method != "PURGE") {
# restart request
set req.http.X-Purge = "Yes";
return (restart);
}
}
sub vcl_hit {
if (obj.ttl >= 0s) {
return (deliver);
}
set req.http.grace = "unlimited (unhealthy server)";
return (deliver);
}
实战WordPress Varnish反向代理
以本站作为反代案例,源站在欧洲某国,国内访问则通过CN2GIA的VPS作为边缘节点
,现在就在这台VPS上安装AMH做反代,在完成以上所有配置之后,开始以下配置
一、首先切换到LNGX反代环境
二、添加反代网站
缓存是用varnish做的,因此后端监听地址这里务必填http://127.0.0.1:6081
,这个是varnish
的监听地址。所以记得要取消LNGX自带的缓存(Cache)。
三、配置varnish
在上面的后端地址已经指定了用varnish
做缓存,所以真正的后端地址的配置就需要在varnish
上做配置了,找到varnish
的配置,在backend
部分指定源站IP和端口:
...
# Setup the backend
backend backend1 {
.host = "1.1.1.1"; # `改为源站IP地址`
.port = "80"; # `改为源站端口`
.first_byte_timeout = 300s;
.connect_timeout = 5s;
.between_bytes_timeout = 5s;
}
backend backend2 {
.host = "1.1.1.1"; # `改为源站IP地址`
.port = "80"; # `改为源站端口`
.first_byte_timeout = 300s;
.connect_timeout = 5s;
.between_bytes_timeout = 5s;
}
...
sub vcl_recv {
...
if (req.http.host ~ "(?i)(^((.*).)?evlit.com)") {
set req.backend_hint = backend1;
} elseif (req.http.host ~ "(?i)(^((.*).)?other.domain.com)") {
set req.backend_hint = backend2;
} else {
return (synth(403, "Hostname not found."));
}
...
}
以上配置中的backend1
是本例的配置关键,backend2则是配置其他域名的。
完成以上配置之后,配置好本机hosts之后,就可以访问了。
但WordPress访问仍然是有问题的,https和http会反复横跳。继续往下看⬇️
四、WordPress配置
打开wp-config.php
,在第二行添加配置:
if ((isset($_ENV["HTTPS"]) && ("on" == $_ENV["HTTPS"]))
|| (isset($_SERVER["HTTP_X_FORWARDED_SSL"]) && (strpos($_SERVER["HTTP_X_FORWARDED_SSL"], "1") !== false))
|| (isset($_SERVER["HTTP_X_FORWARDED_SSL"]) && (strpos($_SERVER["HTTP_X_FORWARDED_SSL"], "on") !== false))
|| (isset($_SERVER["HTTP_CF_VISITOR"]) && (strpos($_SERVER["HTTP_CF_VISITOR"], "https") !== false))
|| (isset($_SERVER["HTTP_CLOUDFRONT_FORWARDED_PROTO"]) && (strpos($_SERVER["HTTP_CLOUDFRONT_FORWARDED_PROTO"], "https") !== false))
|| (isset($_SERVER["HTTP_X_FORWARDED_PROTO"]) && (strpos($_SERVER["HTTP_X_FORWARDED_PROTO"], "https") !== false))
|| (isset($_SERVER["HTTP_X_PROTO"]) && (strpos($_SERVER["HTTP_X_PROTO"], "SSL") !== false))
) {
$_SERVER["HTTPS"] = "on";
}
五、WordPress插件管理缓存
前面提到缓存,如果缓存不能被管理,那么这个缓存就没什么意义。需要到WordPress后台插件搜索varnish
,然后找到 Purge Varnish Cache
安装就好。
安装后激活,然后需要进行配置
配置主要有两个地方,Varnish Control Terminal
是一个varnish的API管理接口,varnish默认监听的是本地回环地址127.0.0.1:6082,但在本例中需要改为公网监听地址。
首先在AMH的varnish的启动参数里面,将127.0.0.1
地址改为0.0.0.0
,这样就可以在公网访问这个高位端口了
Varnish Control Key
则是作为API管理接口的鉴权密钥,可以在linux终端里查看到varnish的启动命令行里找到
这串4f043f13c9891ae61e6f2d2eb
就是密钥了,将它填到wordpress插件里就好了。
最后
AMH默认其实也有缓存的,我没实际测试,主要是我一直以来习惯使用varnish做边缘节点的缓存工具,而且搭配wordpress插件,也可以很方便地刷新缓存,其他的配置,比如发帖自动刷新varnish的缓存,可以直接保持默认就好。
当然,现在你也可以测试一下了。?
您也可以联系文章作者本人进行修改,若内容侵权或非法,可以联系我们进行处理。
任何个人或组织,转载、发布本站文章到任何网站、书籍等各类媒体平台,必须在文末署名文章出处并链接到本站相应文章的URL地址。
本站文章如转载自其他网站,会在文末署名原文出处及原文URL的跳转链接,如有遗漏,烦请告知修正。
如若本站文章侵犯了原著者的合法权益,亦可联系我们进行处理。
hi6个月前0
请问有详细一点的自己搭建的教程吗你好7个月前0
你好,可以再帮我看看吗? 我已经按照你的方法设定了,还是一样,wordpress后台的 Purge Varnish Cache 插件还是清除不到cache,依旧显示 the varnish control terminal is not responding at。谢谢https://mjj.today/i/Srk2Tz https://mjj.today/i/Srkcoi你好7个月前0
对,你说的没错,我配置的时候改了一些东西,现在我按照你的教学,可以启动了,网页可以缓存了,不过wordpress 清除cache 那个插件没用的,我输入本地回环地址127.0.0.1 :6082 ,再输入API key ,插件显示the varnish control terminal is not responding at 127.0.0.1:6082,就你图片那样,然后试一下点击清除cache 那里,他显示error,研究了一天,还是没有不行。你好7个月前1
你好,为啥我按照你的方法,到第三部分,去到真正后源的服务器设定Varnish 部分,我填了真正后源的IP跟端口跟域名,然后重启 Varnish ,就出现这样了? 这是怎么回事? 谢谢[Linux] AMH 7.1 https://amh.sh[varnish-6.6 start] ================================================== =========== [OK] varnish-6.6 is already installed. Could not delete 'vcl_boot.1713549650.959259/vgc.sym': No such file or directory Error: Message from VCC-compiler: VCL version declaration missing Update your VCL to Version 4 syntax, and add vcl 4.1; on the first line of the VCL files. ('/home/usrdata/varnish/default.conf' Line 1 Pos 1) ...#---Running VCC-compiler failed, exited with 2 VCL compilation failedchu7个月前0
很完善的教程‘hu7个月前0
我用gmail EMAIL_SERVER="smtp://********@gmail.com:bpyfv*********chry@smtp.gmail.com:587"叽喳7个月前0
MAIL_SERVER="smtp://no-reply@vort.me:password123@wednesday.mxrouting.net:587"大佬 这个使用outlook 或者gmail 是什么样子的格式? 邮寄已经开启smtp了hu7个月前0
输入框的问题解决了,我没有设置反代,NEXTAUTH_URL改为域名+端口就好了