
Anstatt von meiner Anwendung aus auf externe Bilder zu verlinken, möchte ich sie auf meinem Server zwischenspeichern, auf dem sich meine Webanwendung befindet, z. B. statt
<img src="http://api.domain.com/image/1234.jpeg" />
Ich möchte einen Cache aufrufen, zB
<img src="http://dev:3128/myapp/image?href=http://api.domain.com/image/1234.jpeg">
Wenn Squid also das Bild hat, wird es durchgereicht, andernfalls wird es abgerufen und für das nächste Mal zwischengespeichert. Ist das möglich?
Ich habe Squid installiert und als Reverse-Proxy vor Apache konfiguriert. Meine Konfiguration ist unten (Hostname ist dev):
acl manager proto cache_object
acl localhost src 127.0.0.1/32 ::1
acl to_localhost dst 127.0.0.0/8 0.0.0.0/32 ::1
acl dev_users dstdomain dev
http_access allow dev_users
acl SSL_ports port 443
acl Safe_ports port 80 # http
acl Safe_ports port 21 # ftp
acl Safe_ports port 443 # https
acl Safe_ports port 70 # gopher
acl Safe_ports port 210 # wais
acl Safe_ports port 1025-65535 # unregistered ports
acl Safe_ports port 280 # http-mgmt
acl Safe_ports port 488 # gss-http
acl Safe_ports port 591 # filemaker
acl Safe_ports port 777 # multiling http
acl CONNECT method CONNECT
acl JPEG url_regex -i \.myapp/image?href=http://api.domain.com/image/*.jpeg$
#acl ALL dst 0.0.0.0/0.0.0.0
http_access allow manager localhost
http_access deny manager
http_access deny !Safe_ports
http_access deny CONNECT !SSL_ports
http_access allow localhost
http_access deny all
http_port 3128 accel defaultsite=dev vhost
cache_peer 127.0.0.1 parent 80 0 no-query originserver name=dev
cache_peer_access dev allow dev_users
cache_peer_access dev deny all
cache_dir ufs /var/spool/squid3 100 16 256
coredump_dir /var/spool/squid3
refresh_pattern ^ftp: 1440 20% 10080
refresh_pattern ^gopher: 1440 0% 1440
refresh_pattern -i (/cgi-bin/|\?) 0 0% 0
refresh_pattern (Release|Packages(.gz)*)$ 0 20% 2880
refresh_pattern . 0 20% 4320
never_direct allow JPEG
#always_direct allow ALL
An diesem Punkt scheint der Squid-Proxy zu funktionieren, http://dev:3128/myapp
da er meine PHP-App einwandfrei bedient. Aber ich muss die ALL
ACL-Zeilen auskommentieren (sonst bekomme ich keine Antwort) und Anfragen <img src="http://dev:3128/myapp/image?href=http://api.domain.com/image/1234.jpeg">
werden immer noch im Apache-Zugriffsprotokoll angezeigt (wobei ich nach Squid suche, um sie zwischenzuspeichern/bereitzustellen).
http://dev:3128/myapp/image
ist eigentlich ein PHP-Skript, das das Bild über fopen
und abruft und bereitstellt fpassthru
.
Antwort1
Ich würde die folgende Konfiguration ausprobieren. Ich habe Ihre bereinigt (nicht referenzierte Sachen entfernt) und sie gezwungen, ein Jahr lang alles zwischenzuspeichern und keine Fehler zwischenzuspeichern.
Beachten Sie, dass Squid-Konfigurationen sehr versionsspezifisch sind. Welche Version verwenden Sie also?
cache_dir ufs /var/spool/squid3 100 16 256
coredump_dir /var/spool/squid3
acl localhost src 127.0.0.1 ::1
acl PURGE method PURGE
http_access allow PURGE localhost
acl manager proto cache_object
http_access allow manager localhost
acl dev_users dstdomain dev
http_access allow dev_users
http_port 3128 accel defaultsite=dev vhost
cache_peer 127.0.0.1 parent 80 0 no-query originserver name=dev
cache_peer_access dev allow dev_users
cache_peer_access dev deny all
# Don't cache 404's
negative_ttl 0
# Cache everything for a year
refresh_pattern . 1440 100% 525949 override-expire ignore-reload ignore-no-cache ignore-no-store ignore-must-revalidate ignore-private ignore-auth
#cache JPEG but not anything else
acl JPEG url_regex -i .*image\?href=http.*api.discogs.com.*image.*\.jpeg$
acl to_localhost dst 127.0.0.0/8
cache allow JPEG
cache deny to_localhost
Antwort2
Wenn Squid vor dem Webserver läuft, können Sie eine ACL mit einem regulären Ausdruck einrichten (dazu müssten Sie allerdings einen regulären Ausdruck für alle externen Domänen einrichten). Die Verwendung von könnte funktionieren url_regex
, urlpath_regex
schließt aber den Hostnamen aus. Dies könnte wichtig sein, wenn der Pfad zu den Dateien derselbe ist wie der der auf Ihrem Server gehosteten Dateien.
acl JPGS url_regex -i \.somedomain.com/images/*.jpg$ #Matches JPGs from somedomain
acl GIFS url_regex -i \.somedomain.com/images/*.gif$ #Matches GIFs from somedomain
acl ALL dst 0.0.0.0/0.0.0.0 #Matches Everything else
never_direct allow JPGS
never_direct allow GIFS
always_direct allow ALL
Ich weiß nicht genau, in welcher Situation Sie Squid hier verwenden werden, daher habe ich die klassische Zeile „Alles andere weiterleiten“ hinzugefügt. Wenn Sie nicht den gesamten Internetzugriff über einen Proxy leiten, möchten Sie diesen Bereich möglicherweise neu definieren.
Antwort3
Wenn sich Squid wie ein Cache verhalten soll, müssen Sie Ihr PHP-Skript so konfigurieren, dass Header generiert werden, die das Caching ermöglichen.
Das Minimum, damit Squid tatsächlich etwas zwischenspeichern kann, ist:
- Datum: (wird automatisch von PHP generiert, also kümmern Sie sich nicht darum)
- Zuletzt geändert: GMT-Datum
- Cache-Control: hier einfügen: "public, max-age="
Der einfache Weg besteht dann darin, keinen „Etag:“-Header auszugeben, sodass Sie nur die Anfrage „If-Modified-Since:“ verarbeiten müssen (wenn Sie Etag: ausgeben, müssen Sie auch If-None-Match verarbeiten).
Und los geht‘s.
Wenn Sie tiefer einsteigen möchten, lesen SieRFC 2616.
Wenn Sie den Datenverkehr zwischen Squid und Ihrem Backend effizient reduzieren möchten, implementieren Sie „If-Modified-Since“ korrekt in Ihr Skript. Sie können auch zahlreiche Client-Header löschen/neu schreiben, um das Caching zu verhindern, aber das ist nur ein zweiter Schritt.
Antwort4
Standardmäßig speichert Squid keine URLs mit dem ?-Zeichen im Cache. Versuchen Sie es mit:
cache allow JPEG
Beachten Sie auch, was @Oliver S erwähnt, da Ihre Anwendung den Inhalt zwischenspeicherbar bereitstellen sollte, um zu funktionieren.