
Вместо прямого доступа к внешним изображениям из моего приложения я бы хотел кэшировать их на моем сервере, где находится мое веб-приложение, например, вместо
<img src="http://api.domain.com/image/1234.jpeg" />
Я хотел бы вызвать кэш, например
<img src="http://dev:3128/myapp/image?href=http://api.domain.com/image/1234.jpeg">
Итак, если у Squid есть изображение, он его пропустит, в противном случае он его извлечет и затем кэширует для следующего раза. Возможно ли это?
Я установил squid, настроил его как обратный прокси перед Apache. Мой конфиг ниже (имя хоста — 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
На этом этапе прокси-сервер squid, похоже, работает, http://dev:3128/myapp
так как он отлично обслуживает мое приложение php. Но мне приходится закомментировать ALL
строки acl (иначе я не получаю ответа), а запросы по- <img src="http://dev:3128/myapp/image?href=http://api.domain.com/image/1234.jpeg">
прежнему отображаются в журнале доступа apache (тогда как я ищу squid для их кэширования/обслуживания).
http://dev:3128/myapp/image
на самом деле это PHP-скрипт, который извлекает и обслуживает изображение через fopen
и fpassthru
.
решение1
Я бы попробовал следующую конфигурацию. Я очистил вашу (удали все, на что нет ссылок) и заставил ее кэшировать все на год, а не кэшировать сбои.
Обратите внимание, что конфигурации Squid сильно зависят от версии. Так какую версию вы используете?
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
решение2
Если Squid находится перед веб-сервером, вы можете настроить ACL с регулярным выражением (хотя для этого вам потребуется настроить регулярные выражения для всех внешних доменов), либо с помощью , url_regex
но urlpath_regex
это исключает имя хоста, что может быть важно, если путь к файлам такой же, как и к файлам, размещенным на вашем сервере.
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
Я не знаю точно, в какой ситуации вы будете использовать Squid, поэтому я добавил классическую строку «переслать все остальное». Если вы не проксируете весь доступ в Интернет, вам, возможно, захочется переопределить эту область.
решение3
Если вы хотите, чтобы Squid вел себя как кэш, вам необходимо настроить PHP-скрипт для генерации заголовка, разрешающего кэширование.
Минимальный набор данных, необходимый для кэширования Squid, составляет:
- Дата: (сгенерирована автоматически PHP, так что не беспокойтесь)
- Последнее изменение: дата по Гринвичу
- Cache-Control: поместите сюда: "public, max-age="
Самый простой способ — не выдавать заголовок «Etag:», чтобы вам пришлось обрабатывать только запрос «If-Modified-Since:» (если вы выдаете Etag:, вам придется обрабатывать также и If-None-Match).
И вот, пожалуйста.
Если вы хотите узнать больше, вам следует прочитатьрфк 2616.
Если вы хотите эффективно сократить трафик между squid и вашим бэкэндом, правильно реализуйте "If-Modified-Since" в вашем скрипте. Также вы можете удалить / переписать многочисленные заголовки клиента, которые предотвратят кэширование, но это только второй шаг.
решение4
По умолчанию Squid не кэширует URL-адреса со знаком ?. Попробуйте:
cache allow JPEG
Также обратите внимание на то, что упомянул @Oliver S, потому что ваше приложение должно обслуживать контент как кэшируемый для работы.