Примусити розповсюдження / оновлення файлів CloudFront


146

Я використовую CloudFront Amazon для обслуговування статичних файлів моїх веб-додатків.

Чи немає способу сказати розповсюдженню хмари, що йому потрібно оновити файл або вказати один файл, який слід оновити?

Amazon рекомендує використовувати версії файлів, таких як logo_1.gif, logo_2.gif тощо, як вирішення цієї проблеми, але це здається досить дурним рішенням. Немає зовсім іншого способу?



як сторонне слово, я не думаю, що нерозумно називати статичні файли так. Ми багато використовуємо його, і автоматичне перейменування відповідно до версії файлу в контролі версій врятувало нам багато головних болів.
ейс

1
@eis, якщо файл, який потрібно замінити, не пов’язаний з 1000 різними місцями в Інтернеті. Удачі в оновленні всіх цих посилань.
Джейк Вілсон

@Jakobud Чому в такому випадку слід оновлювати посилання? вони посилаються на конкретну версію, яка не є останньою, якщо файл було змінено. Якщо файл не змінено, він буде працювати, як це було раніше.
eis

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

Відповіді:


134

Гарні новини. Нарешті Amazon додав функцію інваліду. Див. Посилання API .

Це зразок запиту з довідника API:

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 Після подання createInvalidationзапиту на API я все ще бачу, що оновлення потребує 5-10 хвилин або близько того, щоб визнати недійсним. Зауважте, що я пишу цей коментар через 4 роки після вашого.
Тім петерсон

19

Станом на 19 березня, Amazon тепер дозволяє кешу TTL Cloudfront скласти 0 секунд, тому ви (теоретично) ніколи не повинні бачити застарілих об'єктів. Тож якщо у вас є активи в S3, ви можете просто перейти на веб-панель AWS => S3 => Редагувати властивості => Метадані, а потім встановити значення "Кеш-контроль" на "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, а максимальний вік на 0 - це дійсно використання CloudFront без кешування, чи не пересилатиме всі запити на джерело постійно перевіряючи наявність оновлень? По суті робить CDN марним?
acidjazz

6
Якщо ви просто використовуєте cloudfront як механізм для створення статичного S3 з підтримкою SSL-сайту з користувацьким доменом, кешування не має значення. Крім того, ці питання, які ми обговорюємо, полягають у тому, що на етапах розробки кешування 0-разів добре.
Dan G

10

Завдяки API недійсності він оновлюється за кілька хвилин.
Перевірте інвалід PHP .


Це саме те, що я шукав. Я збираюся підключити це до веб-гачків Beanstalkapp при автоматичному розгортанні з git! Дякуємо за посилання!
cointilt

10

Автоматизована установка оновлення за 5 хв

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

Навіть якщо ви ніколи раніше не використовували лямбда-функції, це дуже просто - просто дотримуйтесь моїх покрокових інструкцій, і це займе всього 5 хвилин:

Крок 1

Перейдіть на сторінку https://console.aws.amazon.com/lambda/home і натисніть Створити функцію лямбда.

Крок 2

Клацніть на пусту функцію (спеціальна)

Крок 3

Клацніть на порожньому (погладженому) полі і виберіть S3 з комбо

Крок 4

Виберіть відро (те саме, що і для розповсюдження CloudFront)

Крок 5

Встановіть тип події на "Об'єкт створено (усі)"

Крок 6

Встановіть префікс і суфікс або залиште його порожніми, якщо ви не знаєте, що це таке.

Крок 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

Клацніть перегляд документа про політику , натисніть кнопку " Редагувати" , натисніть " OK" та замініть визначення ролі наступним (як є):

{
  "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

Встановіть пам'ять (MB) на 128, а час очікування - 5 секунд.

Крок 18

Натисніть Далі , потім натисніть кнопку Створити функцію

Крок 19

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

PS - Коли ви тестуєте, переконайтеся, що ваш браузер завантажує зображення з CloudFront, а не з локального кешу.

PSS - Зауважте, що лише перші 1000 недійсних файлів на місяць є безкоштовними, кожна інвалідація понад ліміт коштує 0,005 доларів США. Також можливі додаткові збори за функцію лямбда, але це надзвичайно дешево.


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

@Phil Код написаний таким чином, тому будуть лише невідомі лише завантажені файли, а не ціле відро. У разі завантаження кількох файлів кожен з них буде визнаний недійсним окремо. Працює як шарм.
Кайнакс

Єдина причина, по якій цей код працює, як очікувалося, полягає в тому, що в даний час S3 включав лише один елемент за повідомлення, тобто довжина масиву щасливо завжди 1, а отже, навіть якщо ви завантажуєте декілька файлів за один раз, ви отримуєте абсолютно нове повідомлення на файл. Ви ні в якому разі не отримуєте повідомлення про все відро. Незважаючи на це, цей код, як написано, не готовий, якщо AWS змінить таку поведінку. Набагато безпечніше писати код, який обробляє весь масив, незалежно від довжини, що було моїм оригінальним (на жаль пропущеним) моментом.
Філ

Єдина причина, чому AWS додає обробники подій, це ... добре ... обробляти події. Чому вони б її зняли? Незалежно від того, як доданий новий файл, він повинен викликати події для API, і саме так він працює зараз і буде продовжувати працювати. Я використовую AWS протягом 4 років, і вони ніколи щось не змінювали, тому попередній код перестав працювати. Навіть якщо вони змінюють API, вони змінюють його на нову окрему версію, але всі попередні версії завжди залишаються підтримуваними. У цьому конкретному випадку я просто не вірю, що подія з особистого файлу ніколи не буде видалена. Можливо, це вже використовується мільйонами проектів у всьому світі.
Кайнакс

У випадку, якщо я неправильно зрозумів ваш перший коментар, і ви маєте на увазі, що "Кількість": 1 додасть лише останній елемент - для кожного елемента в масиві є петля FOR.
Кайнакс

9

Bucket Explorer має інтерфейс користувача, який робить це зараз досить просто. Ось як:

Клацніть правою кнопкою миші ваше відро. Виберіть "Управління дистрибутивами".
Клацніть правою кнопкою миші ваш дистрибутив. Виберіть "Отримати список несанкціонованих послуг Cloudfront". Потім виберіть "Створити", щоб створити новий список недійсності. Виберіть файли, які слід визнати недійсними, і натисніть "Недійсний". Зачекайте 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 з скрипту консолі \ bash \ travis ci розгортання. До речі, ось як змінити \ недійсний кеш CoudFront під час розгортання програми aws
Мікіта Манько,

3

Щойно повідомляю, щоб повідомити всіх, хто відвідує цю сторінку (перший результат на "Оновлення файлу Cloudfront"), що на swook.net доступний простий у користуванні + Інтернет-інвалід.

Цей новий інвалід:

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

Повне розкриття: я зробив це. Веселіться!


2
Вибачте, але навіть "ви говорите", що облікові дані не зберігаються і не передаються в обіг ... ніколи не слід передавати свої дані третій стороні. Може реалізувати віддалену автентифікацію Amazon чи щось таке?
д.раєв

Ви повинні принаймні поставити це за https.
Олівер Тайнс

Інтернетні інструменти, як правило, приємно, але надання повноважень стороннім інструментом буде важливою проблемою безпеки. Я б запропонував використовувати або офіційну веб-консоль, або офіційний інструмент CLI .
RayLuo

2
Для безпеки інших людей я забороняю цю відповідь. Ніколи не слід просити людей у ​​їхніх повноважень
Moataz Elmasry

3

один дуже простий спосіб зробити це FOLDER версія.

Отже, якщо, наприклад, ваших статичних файлів сотні, просто покладіть їх у папку, яку називають рік + версія.

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

Тож всередині мого HTML я завжди кладу посилання на папку. (звичайно, у мене є PHP, включте, де я встановив ім'я папки.) Отже, змінивши 1 файл, він фактично зміниться у всіх моїх PHP-файлах ..

Якщо я хочу повністю оновити, я просто перейменую папку на 2014_v2 у своє джерело та зміну всередині php включаю в 2014_v2

всі HTML автоматично змінюються і запитують новий шлях, кешують MISS кеш і запитують його до джерела.

Приклад: SOURCE.mydomain.com - це моє джерело, cloudfront.mydomain.com - це CNAME для розподілу cloudfront.

Тож 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

навіть після недійсного оброблення та оновлення на всіх крайніх серверах Amazon потрібно ще 5-10 хвилин


Ти щойно врятував мені життя!
Фабіо Батіста

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

Чувак, thtat була версія, випущена майже 3 роки тому. Спробуйте останню версію, і ця функція, ймовірно, все ще є. (Повне розкриття інформації: Я більше не працюю над AWS CLI.)
RayLuo

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

0

Перейдіть до CloudFront.

Клацніть свій ідентифікатор / дистрибуції.

Клацніть на інваліди.

Натисніть кнопку Створити недійсну.

У гігантському прикладі введіть поле * та натисніть недійсний

Зроблено

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

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.