MediaWikiでVarnishでキャッシュヒット率を上げるために変更した点など… おかしいぞなどあればコメントください
Manual:Varnish cachingのVCLをコピーしたら「おまかせ表示」までキャッシュしてえらい目にあった😭
環境
- Varnish 6.3 – VCL 4.1
- MediaWiki 1.37
構成例
インターネット | <—> |
|
- IP:203.0.113.1 – MediaWiki(Nginx)サーバ
- IP:203.0.113.10 – Varnishサーバ
(IPアドレスは例示用です)
MediaWiki
MediaWikiは標準で更新時にVarnishのキャッシュをパージ(削除)する機能がついているので設定するだけで使用することができます。
$wgUseCdn = true;
$wgCdnServers = [ '203.0.113.10:80' ];
$wgCdnServersNoPurge = ['203.0.113.10' ]
PURGEリクエスト送る必要のあるIPアドレスを$wgCdnServers
に指定 、Portを指定している場合 $wgCdnServersNoPurge
にもIPアドレスの指定が必要です。 (※X-Forwarded-Forが適切に扱われず編集者のIPアドレスすべて同じになります)
⚓ T132538 isConfiguredProxy not recognizing $wgSquidServers with port
その他設定
$wgCdnMaxAge = 18000; //5 hour
$wgResourceLoaderMaxage = [
'versioned' => 30 * 24 * 60 * 60, // 30 days
'unversioned' => 5 * 60 // 5 minutes
];
$wgInternalServer = 'http://example.com';
$wgCdnMaxAge
記事ページの s-maxage 日付を扱うwikiは短めにしたほうが良いかも
$wgResourceLoaderMaxage
ResourceLoader関連
$wgInternalServer
パージ時に使われるサーバURL $wgServerが https://~と指定していたので http://~ になるアドレスを書いた
Varnish
backend default
にMediaWikiが動作しているサーバIP・Port、acl purge
にも同じIPアドレスを指定します
#
# VCL file for Varnish.
#
vcl 4.1;
backend default {
.host = "203.0.113.1";
.port = "80";
}
# access control list for "purge": open to only localhost and other local nodes
acl purge {
"203.0.113.1";
}
# vcl_recv is called whenever a request is received
sub vcl_recv {
set req.backend_hint= default;
# This uses the ACL action called "purge". Basically if a request to
# PURGE the cache comes from anywhere other than localhost, ignore it.
if (req.method == "PURGE") {
if (!client.ip ~ purge) {
return (synth(405, "Not allowed."));
} else {
return (purge);
}
}
if (req.method == "PRI") {
/* This will never happen in properly formed traffic (see: RFC7540) */
return (synth(405));
}
if (!req.http.host &&
req.esi_level == 0 &&
req.proto ~ "^(?i)HTTP/1.1") {
/* In HTTP/1.1, Host is required. */
return (synth(400));
}
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);
}
if (req.method != "GET" && req.method != "HEAD") {
/* We only deal with GET and HEAD by default */
return (pass);
}
# normalize Accept-Encoding to reduce vary
if (req.http.Accept-Encoding) {
if (req.http.User-Agent ~ "MSIE 6") {
unset req.http.Accept-Encoding;
} elsif (req.http.Accept-Encoding ~ "gzip") {
set req.http.Accept-Encoding = "gzip";
} elsif (req.http.Accept-Encoding ~ "deflate") {
set req.http.Accept-Encoding = "deflate";
} else {
unset req.http.Accept-Encoding;
}
}
#
# Static-File
#
if (req.url ~ "^(\/w\/load.php|\/w\/images|\/w\/resources)") {
unset req.http.Cookie;
return(hash);
}
#
# Authorization Cookie session|Token
#
if (req.http.Authorization || req.http.Cookie ~ "([sS]ession|Token)") {
return (pass);
} /* Not cacheable by default */
#
# Remove _* cookies. Google,Cloudflare...
#
set req.http.Cookie = ";" + req.http.Cookie;
set req.http.Cookie = regsuball(req.http.Cookie, "(^|;\s*)(_[a-zA-Z1-9_]+)=[^;]*", "");;
# Remove a ";" prefix, if present.
set req.http.Cookie = regsub(req.http.Cookie, "^;\s*", "");
return (hash);
}
sub vcl_pipe {
# By default Connection: close is set on all piped requests, to stop
# connection reuse from sending future requests directly to the
# (potentially) wrong backend. If you do want this to happen, you can undo
# it here.
unset bereq.http.connection;
}
sub vcl_backend_response {
# Serve stale content for 2 minutes after object expiration
# Perform asynchronous revalidation while stale content is served
set beresp.grace = 120s;
}
説明
変更した点や解説など
X-Forwarded-For
Varnish 6 からは X-Forwarded-ForはVarnishが自動で追加します
Upgrading to Varnish 6.0 — Varnish version 6.2.3 documentation
Authorization Cookie session|Token
Cookieにsession、Tokenが含まれる場合キャッシュしない。
Static-File
Cookie を送る必要のない静的ファイルはCookieを消しキャッシュヒット率を上げます(wiki構成に応じて変更してください)
ディレクトリ | 説明 |
/w/load.php | ResourceLoader |
/w/images | アップロードされた画像 |
/w/skins/Vector/resources/ | Vector スキンに使われるアイコンなど |
/w/resources/ | 組み込みアイコン (poweredby_mediawiki、編集アイコンなど) |
Remove _* cookies
Google AnalyticsなどのCookieを削除
- _ga Google Analytics
- _ga_~ Google Analytics
- _gads Google AdSense
- __cf~ CloudFlare
{wikiID}mwuser-sessionIdはMediaWiki JS がセットするので削除して良いかも
beresp.grace
grace 非同期でキャッシュを更新する期間を設定
Varnish Grace Modeで非同期にキャッシュを更新する – LCL Engineers’ Blog
参考リンク
- Varnish built-in VCL – Varnish Developer Portal
- Using pipe in Varnish
- Object lifetime: TTL, Grace, Keep – Varnish Software Documentation
- Best practices for using the Vary header | Fastly
- ⚓ T110353 Audit use of cookies
- Manual:Varnish caching – MediaWiki