15

TLDR: Мы должны обмануть кэширование CloudFront 307 путем создания нового поведения кэша для ответов от нашей лямбда-функции.Обновите изображения на лету в CloudFront и сразу же получите их одним и тем же URL: AWS CloudFront -> S3 -> Lambda -> CloudFront

Вы не поверите, насколько мы должны достичь этого. На последнем шаге мы так сильно застряли.

Бизнес-кейс:

Наши магазины приложений изображения в S3 и служит их CloudFront для того, чтобы избежать каких-либо географических медленного падения по всему земному шару. Теперь мы хотим быть очень гибкими с дизайном и иметь возможность запрашивать новые параметры изображения непосредственно в URL CouldFront! Каждый новый размер будет создан по требованию, а затем сохранен в S3, поэтому во второй раз он будет запрошен, будет , который будет работать очень быстро, поскольку он будет существовать в S3, а также будет кэшироваться в CloudFront.

Скажем, пользователь загрузил изображение chucknorris.jpg. только исходное изображение будет сохранено в S3 и Виль быть подан на нашей странице, как это:

//xxxxx.cloudfront.net/chucknorris.jpg

Мы подсчитали, что нам нужно, чтобы отобразить миниатюру 200x200 пикселей. Поэтому мы ставим СРК изображение, чтобы быть в нашем шаблоне:

//xxxxx.cloudfront.net/chucknorris-200x200.jpg

Когда этот новый размер запрашивается Амазонка веб-службы должны обеспечить его летать в том же ковше и с запрошенным ключом. Таким образом, изображение будет загружено в тот же URL-адрес CloudFront.

Я сделал некрасивый рисунок с обзором архитектуры и рабочего процесса о том, как мы делаем это в AWS:

enter image description here

Вот как Python Lambda заканчивается:

return { 
    'statusCode': '301', 
    'headers': {'location': redirect_url}, 
    'body': '' 
} 

Проблема :

Если мы переадресуем функцию Lambda на S3, она работает как шарм. Если мы перенаправляемся на CloudFront, он переходит в цикл перенаправления, потому что CloudFront кэширует 307 (а также 301, 302 и 303). Как только наша функция Lambda перенаправляет CloudFront, CloudFront вызывает API Getaway URL вместо извлечения изображения из S3:

enter image description here

Я хотел бы создать новое поведение кэша в закладке Behaviors настройки CloudFront в. Это поведение не должно кэшировать ответы от Lambda или S3 (не знаю, что именно там происходит внутри), но все равно следует кэшировать любые последующие запросы на это изображение с одинаковым размером. Я пытаюсь установить шаблон пути -\d+x\d+\..+$, добавьте ARN функции лямбда в добавлении «Ассоциация функций лямбда» и установите тип события Origin Response. Рядом с этим, я устанавливаю «TTL по умолчанию» на 0.

Но я не могу сохранить поведение из-за какой-то ошибки:

enter image description here

ли мы на правильном пути, или идея этой «ассоциации лямбда-функции» совершенно по-другому?

+0

Вы должны связаться со службой поддержки AWS относительно этого сообщения об ошибке. Кроме того, вы посмотрели новую функцию Lambda @ Edge от Cloudfront? –

ответ

7

Наконец-то я смог его решить. Хотя это не является структурным решением, оно делает то, что нам нужно.

Во-первых, благодаря ответу Майкла, я использовал шаблоны путей для соответствия всем типам носителей. Во-вторых, страница «Поведение кэш» немного вводила меня в заблуждение: действительно, ассоциация Lambda для Lambda @ Edge, хотя я не видел этого нигде во всплывающих подсказках поведения кэша: все, что вы видите, это просто Lambda. Эта функция не может нам помочь, так как мы не хотим расширять сферу обслуживания AWS с помощью Lambda @ Edge только из-за этой конкретной проблемы.

Вот решение подход:
я определил несколько поведение кэша, по одному на тип носителя, который мы поддерживаем:

enter image description here

Для каждого поведения кэша я установить Default TTL быть 0.

И самый важная часть: В функции лямбды, я добавил Cache-Control заголовок к изменению размеров изображения при вводе их в S3:

s3_resource.Bucket(BUCKET).put_object(Key=new_key, 
             Body=edited_image_obj, 
             CacheControl='max-age=12312312', 
             ContentType=content_type) 

Чтобы проверить, что все работает, теперь я вижу, что новый изображение Dimention подается с заголовком кэша в CloudFront:

enter image description here

+0

Почему так важно добавлять заголовок 'Cache-Control' в изображения с размерами? Мне кажется, что установка 'Default TTL' будет' 0' уже достаточно. Нет? –

+2

Чтобы ответить на мой собственный глупый вопрос. Я прочитал еще одно сообщение в блоге об этом https://sketchboard.io/blog/serverless-image-resize-with-amazon-lambda, которое объясняет, почему нужен «максимальный возраст». Он будет использоваться CloudFront, чтобы определить, как долго кэшировать объект (после первого запуска, который использует значение по умолчанию 0). Отличный вопрос и ответ здесь! @katericata. –

1

Вы на правильном пути ... может быть ... но есть как минимум две проблемы.

«Ассоциация Лямбда-функций», которую вы настраиваете здесь, называется Lambda @ Edge, и она еще не доступна. Единственными пользователями, которые могут получить к нему доступ, являются пользователи, которые подали заявку на участие в ограниченном предварительном просмотре. Ошибка "maximum allowed is 0" означает, что вы не являетесь участником предварительного просмотра. Я не видел никаких объявлений, связанных с тем, когда это будет жить для всех учетных записей.

Но даже если оно доступно, оно не поможет вам, здесь, как вы, кажется, ожидаете, потому что я не верю, что триггер Origin Response позволяет вам что-либо сделать, чтобы вызвать CloudFront, чтобы попробовать другое назначения и следовать за перенаправлением. Если вы видите документацию, которая противоречит этому утверждению, обратитесь к моему вниманию.

Однако ... Lambda @ Edge будет полезен для установки Cache-Control: no-cache на 307, поэтому CloudFront не будет кэшировать его, но самому переадресации все равно нужно будет вернуться в браузер.

Обратите внимание, что Lambda @ Edge поддерживает только Node, а не Python ... так что, возможно, это еще не часть вашего плана. Я не могу сказать, из вопроса.

Read about the [email protected] limited preview.

Вторая проблема:

I am trying to set path pattern -\d+x\d+\..+$

Вы не можете сделать это. Шаблоны путей - это совпадения строк, поддерживающие * подстановочные знаки. Они не являются регулярными выражениями. Вы можете уйти с /*-*x*.jpg, хотя, начиная с multiple wildcards appear to be supported.

+0

Благодарим вас за все разъяснения. Я изменил шаблон пути, как вы предложили, и я предоставил несколько вариантов поведения для всех типов файлов мультимедиа. Что касается Lambda @ Edge, это совершенно несправедливо по отношению к Amazon, чтобы определить его так. Они никогда не упоминают слово «Edge» в диалоговом окне информации всплывающей подсказки. Я не думаю, что Lambda @ Edge удовлетворит наши потребности, более того, в настоящее время он имеет только Node, но мы хотим остаться с Python, поскольку у нас есть наши алгоритмы масштабирования/изменения размера с использованием PIL. – katericata

+0

Я не понимаю, что вы имеете в виду, назвав его «несправедливым». Вы можете использовать функцию Lambda на любом языке с API Gateway за CloudFront, но вы можете только внутренне «перехватывать» и изменять поведение запроса/ответа CloudFront с помощью Lambda @ Edge ... и это (наряду с тем, что Node.js является поддерживаемый язык) довольно четко указано как в [документации Lambda] (http://docs.aws.amazon.com/lambda/latest/dg/lambda-edge.html), так и в документации [CloudFront] (http: // docs.aws.amazon.com/AmazonCloudFront/latest/DeveloperGuide/lambda-at-the-edge.html). Здесь AWS не обманчива. –

+0

Я согласен с вами в том, что официальная документация ясно указывает, что я имел в виду с моим заявлением, что это не указано на странице «Поведение кэш» (также не в сообщении об исключении). Там вы не видите, что слово Edge упоминалось где угодно, и я обнаружил, что это немного вводит в заблуждение. В нашем случае, поскольку мы используем только Lambda, это было удивительно, поскольку Lambda @ Edge - новая услуга в семействе AWS, и в настоящее время она не входит в нашу сферу применения. :) – katericata

Смежные вопросы