Ответ 1
Разве это не может быть пример использования try_files
?
location /p/ {
try_files $uri @s3;
}
location @s3{
proxy_pass http://my_bucket.s3.amazonaws.com;
}
Убедитесь, что на URL-адресе S3 нет ссылки на
Итак, я перемещаю свой сайт из Apache и на Nginx, и у меня возникают проблемы с этим сценарием:
Пользователь загружает фотографию. Эта фотография изменяется, а затем копируется на S3. Если на диске есть подходящая комната (или файл не может быть передан на S3), локальная версия сохраняется.
Мне нужны запросы для этих изображений (например, http://www.mysite.com/p/1_1.jpg), чтобы сначала посмотреть в каталоге p/. Если локальный файл не существует, я хочу проксировать запрос на S3 и отображать изображение (но не перенаправлять).
В Apache я сделал это так:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^p/([0-9]+_[0-9]+\.jpg)$ http://my_bucket.s3.amazonaws.com/$1 [P,L]
Моя попытка реплицировать это поведение в Nginx такова:
location /p/ {
if (-e $request_filename) {
break;
}
proxy_pass http://my_bucket.s3.amazonaws.com/;
}
Что происходит, так это то, что каждый запрос пытается поразить Amazon S3, даже если файл существует на диске (и если он не существует на Amazon, я получаю ошибки.) Если я удалю строку proxy_pass, тогда запросы на файлы на диск DO работать.
Любые идеи о том, как исправить это?
Разве это не может быть пример использования try_files
?
location /p/ {
try_files $uri @s3;
}
location @s3{
proxy_pass http://my_bucket.s3.amazonaws.com;
}
Убедитесь, что на URL-адресе S3 нет ссылки на
Вы можете улучшить конфигурацию прокси-сервера s3, как это. Адаптировано из fooobar.com/questions/423997/...:
location /p/ {
try_files $uri @s3;
}
location @s3 {
set $s3_bucket 'your_bucket.s3.amazonaws.com';
set $url_full '$1';
proxy_http_version 1.1;
proxy_set_header Host $s3_bucket;
proxy_set_header Authorization '';
proxy_hide_header x-amz-id-2;
proxy_hide_header x-amz-request-id;
proxy_hide_header x-amz-meta-server-side-encryption;
proxy_hide_header x-amz-server-side-encryption;
proxy_hide_header Set-Cookie;
proxy_ignore_headers Set-Cookie;
proxy_intercept_errors on;
resolver 8.8.4.4 8.8.8.8 valid=300s;
resolver_timeout 10s;
proxy_pass http://$s3_bucket$url_full;
}
Я решил это решить, проверив, не существует ли файл, и если да, переписывая этот запрос. Затем я обрабатываю повторно написанный запрос и делаю proxy_pass там, например:
location /p/ {
if (!-f $request_filename) {
rewrite ^/p/(.*)$ /ps3/$1 last;
break;
}
}
location /ps3/ {
proxy_pass http://my_bucket.s3.amazonaws.com/;
}
Спасибо за мой пост coderwall:) Для целей кэширования вы можете немного улучшить его:
http {
proxy_cache_path /tmp/cache levels=1:2 keys_zone=S3_CACHE:10m inactive=24h max_size=500m;
proxy_temp_path /tmp/cache/temp;
server {
location ~* ^/cache/(.*) {
proxy_buffering on;
proxy_hide_header Set-Cookie;
proxy_ignore_headers Set-Cookie;
...
proxy_cache S3_CACHE;
proxy_cache_valid 24h;
proxy_pass http://$s3_bucket/$url_full;
}
}
}
Еще одна рекомендация заключается в расширении кэша резольвера до 5 минут:
resolver 8.8.4.4 8.8.8.8 valid=300s;
resolver_timeout 10s;
break
не делает то, что вы ожидаете, что nginx сделает последнее, о чем вы просите об этом, что имеет смысл, если вы начнете копать вокруг создания модулей... но в основном защитите свой прокси-пароль с помощью do-not-exist версия
if (-f $request_filename) {
break;
}
if(!-f $request_filename)
proxy_pass http://s3;
}