img src="" から明示的に呼び出された画像をキャッシュするように Squid を設定します。

img src="" から明示的に呼び出された画像をキャッシュするように Squid を設定します。

アプリケーションから外部画像にホットリンクする代わりに、Webアプリケーションが存在するサーバーに画像をキャッシュしたいのですが、例えば

<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/myappPHP アプリケーションを正常に提供しているので、正常に機能しているようです。ただし、ALLACL 行をコメント アウトする必要があります (そうしないと応答がありません)。また、Apache アクセス ログにはリクエストが<img src="http://dev:3128/myapp/image?href=http://api.domain.com/image/1234.jpeg">引き続き表示されます (Squid がそれらをキャッシュ/提供することを望んでいます)。

http://dev:3128/myapp/imagefopenは、実際には、およびを介して画像を取得して提供する PHP スクリプトですfpassthru

答え1

次の設定を試してみます。あなたの設定をクリーンアップし (参照されていないものを削除)、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 が Web サーバーの前に配置されている場合は、正規表現を使用して ACL を設定できます (ただし、これにはすべての外部ドメインに対して正規表現を設定する必要があります)。 を使用すると機能しますがurl_regexurlpath_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 がどのような状況で使用されるかは正確にはわかりませんので、従来の「forward everything else」行を追加しました。すべてのインターネット アクセスをプロキシしていない場合は、そのスコープを再定義することをお勧めします。

答え3

Squid をキャッシュのように動作させたい場合は、キャッシュを許可するヘッダーを生成するように PHP スクリプトを構成する必要があります。

Squid が実際に何かをキャッシュするために必要な最小値は次のとおりです。

  • 日付: ( PHP によって自動的に生成されるので、気にする必要はありません )
  • 最終更新日: GMT 日付
  • Cache-Control: ここに「public, max-age=」と入力してください

簡単な方法は、「Etag:」ヘッダーを発行しないことです。そうすれば、「If-Modified-Since:」リクエストのみを処理すれば済みます (Etag: を発行する場合は、If-None-Match も処理する必要があります)。

では、どうぞ。

もっと深く知りたい方は、RFC 2616 の

Squid とバックエンド間のトラフィックを効率的に削減したい場合は、スクリプトに「If-Modified-Since」を正しく実装してください。また、多数のクライアント ヘッダーを削除/書き換えてキャッシュを防ぐこともできますが、これは 2 番目のステップにすぎません。

答え4

デフォルトでは、Squid は ? 記号の付いた URL をキャッシュしません。次を試してください:

cache allow JPEG

また、@Oliver S が言及していることにも注意してください。アプリケーションが機能するには、コンテンツをキャッシュ可能なものとして提供する必要があるためです。

関連情報