admin 管理员组文章数量: 887007
AMH
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>** 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 (.0/users-guide/vcl-example-websockets.html)if (req.http.upgrade ~ "(?i)websocket") {return (pipe);}# We only deal with GET and HEAD by defaultif (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 statusset 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 argumentsset req.url = std.querysort(regsub(req.url, "^http[s]?://", ""));# collect all cookiesstd.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 existsif (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 XMLHttpRequestif (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 requestif (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 settingsif (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 pagesif (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 pagesif (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 cartif (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 APIif (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 authif (!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 theseunset 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 algorithmunset 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: (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 itif (req.url ~ "nocache") {set req.http.X-VC-Cacheable = "NO:Not cacheable, nocache in URL";return (pass);}# unset cookie only if no http authif (!req.http.Authorization) {unset req.http.Cookie;}}# Send Surrogate-Capability headers to announce ESI support to backendset 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 resultreturn (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 cacheableif (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-TTLset 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 headerif (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 privateif (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-TTLset 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-TTLset 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-TTLset 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-TTLset 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-TTLset 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-TTLset 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 objectsset beresp.do_gzip = false; # Don't try to compress it for storage# Stream large objects, <= 128 MiBif (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-TTLset 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-TTLset beresp.http.X-VC-TTL = 0;set beresp.ttl = 0s;}}}# Don't cache object as instructed by header bereq.X-VC-Cacheableif (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-TTLset beresp.http.X-VC-TTL = 0;set beresp.ttl = 0s;}# validate if we need to cache it and prevent from setting cookieif (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-TTLif (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 (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 headersunset 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 sitesset 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 discardedif (req.method != "PURGE") {# restart requestset 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)") {set req.backend_hint = backend1;} elseif (req.http.host ~ "(?i)(^((.*).)?other.domain)") {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的缓存,可以直接保持默认就好。
当然,现在你也可以测试一下了。😊
原创文章,转载请著名出处,同时文章同步发表在:
AMH-7.1 面板:实战LNGX+Varnish反向代理,提升Wordpress网站打开速度 - EVLIT
本文标签: AMH
版权声明:本文标题:AMH 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.freenas.com.cn/jishu/1732360827h1535165.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论