Podręcznik: Varnish caching
Varnish to lekki, wydajny[1] serwer reverse proxy, który skraca czas potrzebny na obsługę często pobieranych stron.
Varnish to akcelerator HTTP, który przechowuje kopie stron obsługiwanych przez serwer WWW. Za kazdym razem, gdy zażądana zostanie ta sama strona, Varnish udostępni kopię, zamiast żądać strony z serwera Apache. Ten proces buforowania eliminuje potrzebę ponownego generowania tej samej strony przez MediaWiki, co skutkuje ogromnym wzrostem wydajności.[2]
Varnish ma tę zaletę, że został zaprojektowany specjalnie do użytku jako akcelerator HTTP (odwrotne proxy). Przechowuje większość danych w pamięci podręcznej w pamięci, tworząc mniej plików dyskowych i mniej dostępów do systemu plików niż większy, bardziej uniwersalny pakiet Squid . Podobnie jak Squid, obsługuje często ładowane strony dla anonimowych użytkowników IP z pamięci podręcznej, zamiast żądać ich z oryginalnego serwera WWW. To zmniejsza zarówno wykorzystanie procesora CPU, jak i dostęp do bazy danych przez podstawowy serwer MediaWiki.
Ze względu na ten wzrost wydajności, MediaWiki zostało zaprojektowane tak, aby ściśle integrować się z pamięcią podręczną sieci Web i powiadomi Squida lub Varnisha, kiedy strona powinna zostać usunięta z pamięci podręcznej w celu jej ponownego zregenerowania.
Z punktu widzenia MediaWiki, poprawnie skonfigurowana instalacja Varnish jest wymienna z jej odpowiednikiem Squid.
Architektura
Przykładowa konfiguracja Varnish, Apache i MediaWiki na jednym serwerze jest opisana poniżej. Bardziej złożona strategia buforowania może wykorzystywać wiele serwerów WWW znajdujących się za tymi samymi pamięciami podręcznymi Varnish (z których wszystkie mogą wyglądać jak jeden host) lub używać niezależnych serwerów do dostarczania treści wiki lub obrazów.
Świat zewnętrzny | ↔ |
Serwer
|
Dla świata zewnętrznego, Varnish wydaje się działać jako serwer internetowy. W rzeczywistości przekazuje on żądania do serwera internetowego Apache, ale tylko wtedy, gdy jest to konieczne. Apache działający na tym samym serwerze nasłuchuje tylko żądań z hosta lokalnego (127.0.0.1), podczas gdy Varnish nasłuchuje tylko żądań na zewnętrzny adres IP serwera. Obie usługi działają na porcie 80 bez konfliktów, ponieważ każda z nich jest związana z różnymi adresami IP.
Konfiguracja Varnish
Poniższa konfiguracja działa dla Varnish w wersji 4 i nowszych.
vcl 4.0;
# set default backend if no server cluster specified
backend default {
.host = "127.0.0.1";
.port = "8080";
# .port = "80" led to issues with competing for the port with apache.
}
# access control list for "purge": open to only localhost and other local nodes
acl purge {
"127.0.0.1";
}
# vcl_recv is called whenever a request is received
sub vcl_recv {
# Serve objects up to 2 minutes past their expiry if the backend
# is slow to respond.
# set req.grace = 120s;
set req.http.X-Forwarded-For = req.http.X-Forwarded-For + ", " + client.ip;
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);
}
}
# Pass requests from logged-in users directly.
# Only detect cookies with "session" and "Token" in file name, otherwise nothing get cached.
if (req.http.Authorization || req.http.Cookie ~ "([sS]ession|Token)=") {
return (pass);
} /* Not cacheable by default */
# 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;
}
}
return (hash);
}
sub vcl_pipe {
# Note that only the first request to the backend will have
# X-Forwarded-For set. If you use X-Forwarded-For and want to
# have it set for all requests, make sure to have:
# set req.http.connection = "close";
# This is otherwise not necessary if you do not do any request rewriting.
set req.http.connection = "close";
}
# Called if the cache has a copy of the page.
sub vcl_hit {
if (!obj.ttl > 0s) {
return (pass);
}
}
# Called after a document has been successfully retrieved from the backend.
sub vcl_backend_response {
# Don't cache 50x responses
if (beresp.status == 500 || beresp.status == 502 || beresp.status == 503 || beresp.status == 504) {
set beresp.uncacheable = true;
return (deliver);
}
if (!beresp.ttl > 0s) {
set beresp.uncacheable = true;
return (deliver);
}
if (beresp.http.Set-Cookie) {
set beresp.uncacheable = true;
return (deliver);
}
if (beresp.http.Authorization && !beresp.http.Cache-Control ~ "public") {
set beresp.uncacheable = true;
return (deliver);
}
return (deliver);
}
Konfigurowanie MediaWiki
Ponieważ Varnish wykonuje żądania z localhost, Apache otrzyma "127.0.0.1" jako bezpośredni adres zdalny. Jednakże, gdy Varnish przekazuje żądania do Apache, jest skonfigurowany do dodawania nagłówka "X-Forwarded-For", aby zachować zdalny adres ze świata zewnętrznego. MediaWiki musi być skonfigurowana tak, aby używała nagłówka "X-Forwarded-For", aby poprawnie wyświetlać adresy użytkowników w special:recentchanges.
Wymagana konfiguracja jest taka sama dla Squid jak dla Varnish. Upewnij się, że plik LocalSettings.php zawiera następujące wiersze:
$wgUseCdn = true;
$wgCdnServers = [ '127.0.0.1', '192.168.0.1' ];
//Use $wgCdnServersNoPurge if you don't want MediaWiki to purge modified pages
//$wgCdnServersNoPurge = [ '192.168.0.2' ];
Należy pamiętać, aby zastąpić "192.168.0.1" adresem IP, na którym nasłuchuje pamięć podręczna Varnish. Te ustawienia służą dwóm celom:
- Jeśli żądanie zostanie odebrane z serwera cache Varnish, w logach MediaWiki musi być wyświetlany adres IP użytkownika, a nie adres IP Varnish. special:recentchanges, w której każda edycja jest zgłaszana jako '127.0.0.1', jest prawie bezużyteczna; Umieszczenie tego adresu jako serwera Squid/Varnish mówi MediaWiki, aby zignorowało adres IP i zamiast tego patrzeć na nagłówek "x-forwarded-for" dla adresu IP użytkownika.
- Jeśli strona lub obraz zostanie zmieniony na wiki, MediaWiki wyśle powiadomienie do każdego serwera wymienionego w $wgCdnServers z informacją, aby odrzucił (usunął) nieaktualną przechowywaną stronę.
Użyj $wgCdnServersNoPurge dla adresów, które muszą być wyłączone z ostatnich zmian, ale które nie otrzymują wiadomości HTTP PURGE. Na przykład, jeśli Apache i Squid są odpowiednio na 127.0.0.1 i adres zewnętrzny jest na tej samej maszynie, to nie ma potrzeby wysyłania Apache wiadomości "wyczyść" przeznaczonej dla Squid. Podobnie, jeśli Squid nasłuchuje wielu adresów, wyślij wiadomość "purge" tylko do jednego z nich.
Zobacz też Ustawienia konfiguracyjne Squid dla wszystkich ustawień związanych z buforowaniem Squid/Varnish.
Jeśli używasz HTTPS, upewnij się, że ustawisz $wgInternalServer na tę samą wartość jak $wgServer ale z protokołem http://, aby zapobiec przesyłaniu żądań o wyczyszczenie jako HTTPS.
If using $wgForceHTTPS , be sure to send request header "X-Forwarded-Proto: https" to suppress the redirect, otherwise disable $wgForceHTTPS to prevent redirect loops.
Kilka uwag
Zauważ, że Varnish jest alternatywą dla Squid, ale nie zastępuje innych części kompletnej strategii buforowania MediaWiki buforowanie, takich jak:
- Wstępnie skompilowany kod PHP
- Domyślnym zachowaniem PHP w Apache jest ładowanie i interpretacja skryptów internetowych PHP za każdym razem, gdy są one dostępne. Instalacja pamięci podręcznej, takiej jak APC (
yum install php-pecl-apc
, a następnie przydzielenie pamięci, ustawiającapc.shm_size=128
lub lepiej w/etc/php.d/apc.ini
) może znacznie zmniejszyć ilość czasu procesora wymaganego przez Apache do obsługi zawartości PHP. - Lokalizacja/internacjonalizacja
- Domyślnie MediaWiki tworzy ogromną tabelę bazy danych
l10n_cache
i stale z niej korzysta - co może więcej niż podwajać obciążenie serwera bazy danych po "aktualnieniu" do najnowszej wersji MediaWiki. Ustaw $wgLocalisationCacheConf w celu wymuszenia przechowywania informacji o lokalizacji w systemie plików, aby to naprawić. - Zmienne i dane sesji
- Przechowywanie zmiennych danych, takich jak pasek boczny MediaWiki, lista przestrzeni nazw lub lista spamu w pamięci podręcznej znacznie zwiększy szybkość instalacji MediaWiki. Wymuszanie przechowywania danych logowania użytkownika we wspólnej lokalizacji jest również niezbędne dla każdej instalacji, w której wiele wymiennych serwerów Apache jest ukrytych za tymi samymi pamięciami podręcznymi Varnish, aby serwować strony dla tych samych wiki. Zainstaluj pakiet memcached i ustaw następujące opcje w LocalSettings.php w celu wymuszenia zarówno informacji o logowaniu użytkownika, jak i buforowanych zmiennych do użycia memcache:
$wgMainCacheType = CACHE_MEMCACHED;
$wgMemCachedServers = [ '127.0.0.1:11211' ];
- Pamiętaj, że jeśli masz wiele serwerów, adres localhost musi zostać zastąpiony adresem współdzielonych serwerów memcached, który musi być taki sam dla wszystkich pasujących serwerów WWW w Twojej witrynie. Gwarantuje to, że zalogowanie użytkownika do jednego serwera w klastrze spowoduje zalogowanie go na wiki na wszystkich wymiennych serwerach WWW.
W wielu przypadkach istnieje wiele alternatywnych podejść do buforowania, które dają ten sam wynik. Zobacz Manual:Cache .
Konfiguracja Apache
Plik dziennika
Dziennik (log) serwera WWW Apache domyślnie pokazuje tylko adres serwera pamięci podręcznej Varnish, w tym przykładzie "127.0.0.1:80"
Apache może być skonfigurowany do rejestrowania oryginalnego adresu użytkownika poprzez przechwytywanie informacji "x-forwarded-for" w niestandardowym formacie pliku dziennika.[3]
Przykładem dla httpd.conf Apache do skonfigurowania logowania x-forwarded-for jest:
LogFormat "%{X-Forwarded-for}i %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" cached
Hot-linkowanie obrazów
Jeśli strona używa funkcji Apache mod_rewrite
do blokowania prób dostępu innych stron internetowych wprowadzających obrazy z hotlinkami, ta konfiguracja będzie musiała zostać usunięta, a równoważna konfiguracja dodana do plików konfiguracyjnych Varnish.
Tam, gdzie serwer obrazów znajduje się za Varnishem, zazwyczaj 90% lub więcej typowych żądań obrazów nigdy nie dociera do Apache i dlatego nie zostaną one zablokowane przez sprawdzenie "http_referer" w konfiguracjach Apache.
Zobacz też