Принудительный дистрибутив CloudFront / обновление файлов


146

Я использую AmazonF CloudFront для обслуживания статических файлов моих веб-приложений.

Нет ли способа сообщить дистрибутиву Cloudfront, что ему нужно обновить свой файл, или указать один файл, который нужно обновить?

Amazon рекомендует в качестве обходного пути для этой проблемы установить версии файлов, таких как logo_1.gif, logo_2.gif и т. Д., Но это кажется довольно глупым решением. Разве нет другого пути?



как sidenote, я не думаю, что глупо называть статические файлы такими. Мы много использовали его, и автоматическое переименование по версии файла в управлении версиями избавило нас от многих головных болей.
эйс

1
@eis, если файл, который нужно заменить, не был связан с 1000 различными местами в Интернете. Удачи в обновлении всех этих ссылок.
Джейк Уилсон,

@Jakobud, почему ссылки должны быть обновлены в этом случае? они ссылаются на конкретную версию, которая не является последней, если файл был изменен. Если файл не был изменен, он будет работать как раньше.
Eis

6
В некоторых случаях компания может сделать ошибку, разместив неправильное изображение для чего-либо или какого-либо другого типа элемента, когда они получают уведомление об удалении из юридической фирмы и должны заменить файл. Простая загрузка нового файла с новым именем не решит такую ​​проблему, которая, к сожалению, встречается все чаще и чаще.
Джейк Уилсон

Ответы:


134

Хорошие новости. Amazon наконец-то добавил функцию недействительности. См. Справочник по API .

Это пример запроса от API Reference:

POST /2010-08-01/distribution/[distribution ID]/invalidation HTTP/1.0
Host: cloudfront.amazonaws.com
Authorization: [AWS authentication string]
Content-Type: text/xml

<InvalidationBatch>
   <Path>/image1.jpg</Path>
   <Path>/image2.jpg</Path>
   <Path>/videos/movie.flv</Path>
   <CallerReference>my-batch</CallerReference>
</InvalidationBatch>

9
Обратите внимание, что аннулирование займет некоторое время (очевидно, 5-30 минут, согласно некоторым сообщениям в блоге, которые я прочитал).
Майкл Варкентин

37
Если вы не хотите самостоятельно отправлять запрос API, вы также можете войти в консоль Amazon и создать там запрос на аннулирование
j0nes

Для тех из вас, кто использует API для аннулирования, приблизительно, сколько времени потребуется, чтобы аннулирование вступило в силу?
ill_always_be_a_warriors

20
Помните, это стоит $ 0,005 за файл после ваших первых 1000 запросов о признании недействительными в месяц aws.amazon.com/cloudfront/pricing
TimS

1
@MichaelWarkentin После того, как я сделал запрос API createInvalidation, я все еще вижу, что обновление занимает 5-10 минут или около того, чтобы сделать его недействительным. Заметьте, я пишу этот комментарий через 4 года после вашего.
Тим Петерсон

19

По состоянию на 19 марта Amazon теперь позволяет TTL кэша Cloudfront равняться 0 секундам, поэтому вы (теоретически) никогда не должны видеть устаревшие объекты. Поэтому, если у вас есть ресурсы в S3, вы можете просто перейти на веб-панель AWS => S3 => Изменить свойства => Метаданные, а затем установить значение «Cache-Control» на «max-age = 0».

Это прямо из документации API :

Чтобы контролировать, кэширует ли CloudFront объект и как долго, мы рекомендуем использовать заголовок Cache-Control с директивой max-age =. CloudFront кэширует объект в течение указанного количества секунд. (Минимальное значение составляет 0 секунд.)


Где эта настройка в новом интерфейсе консоли AWS? Я не могу найти это.
ill_always_be_a_warriors

1
Я нашел настройку для отдельного файла, но есть ли настройка, чтобы сделать так, чтобы что-либо загруженное в мое ведро имело TTL 0?
ill_always_be_a_warriors

В то время как я также определенно был бы заинтересован в настройке всей области, я нашел это более быстрое / лучшее решение. Запросы на аннулирование (вместе с остальной частью API) очень запутаны и плохо документированы, и я вращал свои колеса в течение 3 часов, прежде чем это мгновенно сработало.
Двухразрядный алхимик

33
Считай меня сумасшедшим, но установка TTL на 0 и max-age на 0 действительно использует CloudFront без кэширования, разве это не будет пересылать все запросы источнику, постоянно проверяя наличие обновлений? По сути, делает CDN бесполезным?
acidjazz

6
Если вы просто используете cloudfront в качестве механизма для создания статического сайта S3 с поддержкой SSL и настраиваемого домена, кэширование не имеет значения. Кроме того, эти вопросы, которые мы обсуждаем, заключаются в том, что на этапах разработки хорошо подходит 0-временное кэширование.
Дан Г

10

С Invalidation API он обновляется за несколько минут.
Проверьте PHP Invalidator .


Это именно то, что я искал. Я собираюсь подключить это к веб-хукам Beanstalkapp при автоматическом развертывании из git! Спасибо за ссылку!
cointilt

10

Автоматическая настройка обновления за 5 минут

Хорошо, парни. На данный момент лучший способ выполнить автоматическое обновление CloudFront (аннулирование) - создать функцию Lambda, которая будет запускаться каждый раз, когда какой-либо файл загружается в корзину S3 (новый или перезаписывается).

Даже если вы никогда раньше не использовали лямбда-функции, это действительно просто - просто следуйте моим пошаговым инструкциям, и это займет всего 5 минут:

Шаг 1

Перейдите на https://console.aws.amazon.com/lambda/home и нажмите « Создать лямбда-функцию».

Шаг 2

Нажмите на пустую функцию (на заказ)

Шаг 3

Нажмите на пустое (обведенное) поле и выберите S3 из списка

Шаг 4

Выберите ваш Bucket (так же, как для дистрибутива CloudFront)

Шаг 5

Установите тип события «Объект создан (все)»

Шаг 6

Установите Prefix и Suffix или оставьте его пустым, если вы не знаете, что это такое.

Шаг 7

Установите флажок Включить триггер и нажмите Далее

Шаг 8

Назовите свою функцию (что-то вроде: YourBucketNameS3ToCloudFrontOnCreateAll )

Шаг 9

Выберите Python 2.7 (или выше) в качестве среды выполнения

Шаг 10

Вставьте следующий код вместо кода Python по умолчанию:

from __future__ import print_function

import boto3
import time

def lambda_handler(event, context):
    for items in event["Records"]:
        path = "/" + items["s3"]["object"]["key"]
        print(path)
        client = boto3.client('cloudfront')
        invalidation = client.create_invalidation(DistributionId='_YOUR_DISTRIBUTION_ID_',
            InvalidationBatch={
            'Paths': {
            'Quantity': 1,
            'Items': [path]
            },
            'CallerReference': str(time.time())
            })

Шаг 11

Откройте https://console.aws.amazon.com/cloudfront/home на новой вкладке браузера и скопируйте свой идентификатор распространения CloudFront для использования на следующем шаге.

Шаг 12

Вернитесь на лямбда-вкладку и вставьте свой идентификатор распространения вместо _YOUR_DISTRIBUTION_ID_ в коде Python. Держите окружающие цитаты.

Шаг 13

Установить обработчик : lambda_function.lambda_handler

Шаг 14

Нажмите на поле со списком ролей и выберите « Создать пользовательскую роль» . Откроется новая вкладка в браузере.

Шаг 15

Щелкните « Просмотр документа политики» , нажмите « Изменить» , нажмите « ОК» и замените определение роли следующим (как есть):

{
  "Version": "2012-10-17",
  "Statement": [
    {
      "Effect": "Allow",
      "Action": [
        "logs:CreateLogGroup",
        "logs:CreateLogStream",
        "logs:PutLogEvents"
      ],
      "Resource": "arn:aws:logs:*:*:*"
    },
    {
      "Effect": "Allow",
      "Action": [
          "cloudfront:CreateInvalidation"
      ],
      "Resource": [
          "*"
      ]
    }
  ]
}

Шаг 16

Нажмите разрешить . Это вернет вас к лямбде. Дважды проверьте, что только что созданное вами имя роли выбрано в поле со списком Существующие роли .

Шаг 17

Установите для памяти (МБ) значение 128, а для параметра Время ожидания - 5 секунд.

Шаг 18

Нажмите Далее , затем нажмите Создать функцию

Шаг 19

Вы хороши, чтобы пойти! Теперь каждый раз, когда вы будете загружать / перезагружать любой файл в S3, он будет оцениваться во всех местах CloudFront Edge.

PS - Когда вы тестируете, убедитесь, что ваш браузер загружает изображения из CloudFront, а не из локального кэша.

PSS - Обратите внимание, что только первые 1000 недействительных файлов в месяц являются бесплатными, каждая недействительность сверх лимита стоит $ 0,005. Также может взиматься дополнительная плата за функцию лямбда, но это очень дешево.


Только последний элемент из каждой партии S3?
Фил

@Phil Код написан таким образом, что только новые загруженные файлы будут признаны недействительными, а не целое ведро. В случае загрузки нескольких файлов каждый из них будет аннулирован отдельно. Работает как шарм.
Kainax

Единственная причина, по которой этот код работает должным образом, заключается в том, что S3 в настоящее время включает только один элемент в уведомление, т. Е. Длина массива всегда равна 1, и, следовательно, даже если вы загружаете несколько файлов за один раз, вы получаете совершенно новое уведомление за файл. Вы не получите уведомление для всего ведра в любом случае. Тем не менее этот написанный код не готов, если AWS изменит это поведение. Гораздо безопаснее писать код, который обрабатывает весь массив, независимо от длины, которая была моей первоначальной (к сожалению, пропущенной) точкой.
Фил

Единственная причина, по которой AWS добавляет обработчики событий - это ... хорошо ... для обработки событий. Зачем им это убирать? Независимо от того, как был добавлен новый файл, он должен вызывать событие для API, и именно так он работает сейчас и будет продолжать работать. Я использую AWS в течение 4 лет, и они никогда ничего не меняли, поэтому предыдущий код перестал работать. Даже если они меняют API, они меняют его на новую автономную версию, но все предыдущие версии всегда остаются поддерживаемыми. В этом конкретном случае я просто не верю, что событие личного файла когда-либо будет удалено. Вероятно, он уже используется миллионами проектов по всему миру.
Kainax

В случае, если я неправильно понял ваш первый комментарий, и вы имеете в виду, что «Количество»: 1 добавит только последний элемент - для каждого элемента в массиве есть цикл FOR.
Kainax

9

Bucket Explorer имеет пользовательский интерфейс, который делает это довольно легко сейчас. Вот как:

Щелкните правой кнопкой мыши ваше ведро. Выберите «Управление дистрибутивами».
Щелкните правой кнопкой мыши ваш дистрибутив. Выберите «Получить список недействительности Cloudfront». Затем нажмите «Создать», чтобы создать новый список недействительности. Выберите файлы для аннулирования и нажмите «Invalidate». Подождите 5-15 минут.


4

Если у вас установлен boto (который не только для python, но также устанавливает кучу полезных утилит командной строки), он предлагает утилиту командной строки, называемую специально cfadminили «cloud front admin», которая предлагает следующие функциональные возможности:

Usage: cfadmin [command]
cmd - Print help message, optionally about a specific function
help - Print help message, optionally about a specific function
invalidate - Create a cloudfront invalidation request
ls - List all distributions and streaming distributions

Вы обесцениваете вещи, запустив:

$sam# cfadmin invalidate <distribution> <path>

На самом деле cfadmin - очень полезный инструмент, особенно если вам необходимо сбросить кэш CloudFront из сценария развертывания console \ bash \ travis ci. Кстати, вот пост о том, как сбросить / сделать недействительным кеш CoudFront во время развертывания travis в aws
Микита Манько,

3

Просто отправьте сообщение любому посетителю этой страницы (первый результат в «Обновлении файла Cloudfront») о том, что на swook.net имеется простой в использовании сетевой доступный доступный инвалидатор.

Этот новый инвалидатор:

  • Полностью онлайн (без установки)
  • Доступно 24x7 (размещено в Google) и не требует членства.
  • Есть поддержка истории и проверка пути, чтобы вы могли легко сделать ваши файлы недействительными. (Часто с помощью нескольких щелчков мыши после отмены в первый раз!)
  • Это также очень безопасно, как вы узнаете, читая его релиз .

Полное раскрытие: я сделал это. Радоваться, веселиться!


2
извините, но даже «вы говорите» учетные данные не хранятся или не просматриваются ... никогда не следует передавать свои учетные данные третьим лицам. Может быть, реализовать удаленную аутентификацию Amazon или что-то?
д.раев

Вы должны оставить это как минимум за https.
Оливер Тайнс

Онлайн-инструменты, как правило, хороши, но предоставление учетных данных сторонним инструментам будет серьезной проблемой безопасности. Я бы предложил использовать либо официальную веб-консоль, либо официальный инструмент CLI .
RayLuo

2
Для безопасности других, я опускаю этот ответ. Вы никогда не должны спрашивать людей об их полномочиях
Моатаз Эльмасри

3

Один очень простой способ сделать это - верстка FOLDER.

Так что, если ваши статические файлы, например, сотни, просто поместите их все в папку с именем год + версия.

например, я использую папку с именем 2014_v1, где внутри у меня есть все мои статические файлы ...

Так что внутри моего HTML я всегда помещаю ссылку на папку. (конечно, у меня есть PHP include, где я установил имя папки.) Таким образом, изменив в 1 файле, он фактически изменится во всех моих PHP файлах ..

Если я хочу полное обновление, я просто переименую папку в 2014_v2 в мой источник и изменим в php include на 2014_v2

Все HTML автоматически изменяются и запрашивают новый путь, MISS-кэш облака и запрашивают его у источника.

Пример: SOURCE.mydomain.com - мой источник, cloudfront.mydomain.com - это CNAME для распространения на облачном фронте.

Таким образом, PHP назвал этот файл cloudfront.mydomain.com/2014_v1/javascript.js, и когда я хочу полное обновление, просто переименовываю папку в исходный код в «2014_v2» и меняю включение PHP, устанавливая папку в «2014_v2» ,

Таким образом, нет никаких задержек для признания недействительными и никакой цены!

Это мой первый пост в stackoverflow, надеюсь, я сделал это хорошо!



2

В рубине, используя камень тумана

AWS_ACCESS_KEY = ENV['AWS_ACCESS_KEY_ID']
AWS_SECRET_KEY = ENV['AWS_SECRET_ACCESS_KEY']
AWS_DISTRIBUTION_ID = ENV['AWS_DISTRIBUTION_ID']

conn = Fog::CDN.new(
    :provider => 'AWS',
    :aws_access_key_id => AWS_ACCESS_KEY,
    :aws_secret_access_key => AWS_SECRET_KEY
)

images = ['/path/to/image1.jpg', '/path/to/another/image2.jpg']

conn.post_invalidation AWS_DISTRIBUTION_ID, images

даже при аннулировании все еще требуется 5-10 минут для обработки и обновления аннулирования на всех пограничных серверах Amazon


Вы только что спасли мою жизнь!
Фабио Батиста

2

текущая поддержка AWS CLI признана недействительной в режиме предварительного просмотра. Запустите следующее в своей консоли один раз:

aws configure set preview.cloudfront true

Я развернул свой веб-проект, используя npm. У меня есть следующие скрипты в моем package.json:

{
    "build.prod": "ng build --prod --aot",
    "aws.deploy": "aws s3 sync dist/ s3://www.mywebsite.com --delete --region us-east-1",
    "aws.invalidate": "aws cloudfront create-invalidation --distribution-id [MY_DISTRIBUTION_ID] --paths /",
    "deploy": "npm run build.prod && npm run aws.deploy && npm run aws.invalidate"
}

Имея указанные выше сценарии, вы можете развернуть свой сайт с помощью:

npm run deploy

1
Я думаю, вам нужна звездочка в вашей команде 'aws.invalidate', измените --paths /на --paths /*. мой тоже был похож на твой, и это не сделало недействительным распределение ...
Herald Smit

1

Если вы используете AWS, вы, вероятно, также используете его официальный инструмент CLI (рано или поздно). AWS CLI версии 1.9.12 или выше поддерживает аннулирование списка имен файлов.

Полное раскрытие: я сделал это. Радоваться, веселиться!


Мертвая ссылка - ведет к 404 :(, и я не могу обновить его, поскольку версия 1.9.12 отсутствует в примечаниях к выпуску ( aws.amazon.com/releasenotes/?tag=releasenotes%23keywords%23cli )
SlyDave

Чувак, это была версия, выпущенная почти 3 года назад. Попробуйте последнюю версию, и функция, вероятно, все еще там. (Полное раскрытие: я больше не работаю с CLI AWS.)
RayLuo

о, я знаю, просто показалось странным, что из всех примечаний к выпуску только 1.9.12 не существует: D (это то, что я понял из-за невозможности обновить ссылку). Комментарий был больше подсказкой для любого, кто нашел здесь путь, как я и сделал, чтобы найти примечания к выпуску для CLI AWS. нет вреда, нет фола.
SlyDave

0

Перейти к CloudFront.

Нажмите на свой ID / Распределения.

Нажмите на Invalidations.

Нажмите создать Invalidation.

В гигантском поле для примера введите * и нажмите кнопку «аннулировать»

Готово

введите описание изображения здесь

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.