Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
月間7500万PVのサービスのCDNをFastlyに移行してみた
Search
shinyasakurai
November 10, 2023
Programming
0
270
月間7500万PVのサービスのCDNをFastlyに移行してみた
Fastly社主催のYamagoya 2023で登壇したときの発表資料です。
https://v2.nex-pro.com/campaign/60418/apply
shinyasakurai
November 10, 2023
Tweet
Share
More Decks by shinyasakurai
See All by shinyasakurai
技術的負債との戦い! PR TIMESエンジニアチームの オブザーバビリティ改善ジャーニー #devsumi
shinyasakurai
1
1.8k
Other Decks in Programming
See All in Programming
rbs-inlineを導入してYARDからRBSに移行する
euglena1215
1
200
大公開!iOS開発の悩みトップ5 〜iOSDC Japan 2024〜
ryunakayama
0
180
現代のVueとTypeScript - 型安全の活用術
minako__ph
4
3.1k
Playwrightから始めるVisual Regression Testingのススメ by とっと
totto2727
2
1.8k
楽しく簡単に!QRコードの読み取り機能を実装しよう
penguinsan_pg
1
190
Ruby Parser progress report 2024
yui_knk
2
180
プログラマのための音楽入門
cheebow
4
540
Web技術を駆使してユーザーの画面を「録画」する
yukukotani
13
6.2k
Mergeable Libraryで 高速なアプリ起動を実現しよう!
giginet
PRO
1
1.8k
Using Livebook to build and deploy internal tools @ ElixirConf 2024
hugobarauna
0
210
Method Swizzlingを行うライブラリにおけるマルチモジュール設計
yoshikma
0
100
TypeScriptで 負荷テストを書こう 〜k6のシングルバイナリの秘密〜
dora1998
7
2.8k
Featured
See All Featured
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
26
1.9k
GraphQLとの向き合い方2022年版
quramy
43
13k
Building an army of robots
kneath
302
42k
Fontdeck: Realign not Redesign
paulrobertlloyd
80
5.1k
The Mythical Team-Month
searls
218
43k
How to name files
jennybc
75
97k
実際に使うSQLの書き方 徹底解説 / pgcon21j-tutorial
soudai
165
48k
Fantastic passwords and where to find them - at NoRuKo
philnash
47
2.7k
Docker and Python
trallard
39
3k
Navigating Team Friction
lara
183
13k
Facilitating Awesome Meetings
lara
49
5.9k
GraphQLの誤解/rethinking-graphql
sonatard
65
9.7k
Transcript
月間7500万PVのサービスの CDNをFastlyに移行してみた @Yamagoya 2023 PR TIMES 開発本部 インフラチームテックリード 櫻井 慎也
自己紹介 櫻井 慎也 PR TIMES 新卒6年目 開発本部 インフラチーム テックリード https://developers.prtimes.jp/2023/04/18/prtimes-cdn-fastly/
https://developers.prtimes.jp/2022/12/01/prtimes-aws-migration/ https://developers.prtimes.jp/2023/09/07/newrelic_extension/
プレスリリース配信サービス PR TIMESについて
None
None
2022年2月にFastly ImageOptimizerを導入して 一部のプレスリリース画像の画質を改善しました https://developers.prtimes.jp/2022/02/24/press_release_image_optimization/ 当時新卒一年目の メンバーが やり遂げてくれま した 🙌
None
圧縮率の高い画像形式である WebPを使うことで 画像の高画質化と軽量化を 両立!
2023年3月にはPR TIMES STORYでAVIFやWebP 画像を配信するのにImageOptimizerを活用しました https://developers.prtimes.jp/2023/03/02/use_avif_and_webp_for_story_thumbnail_images/
スマートフォンページのLighthouseの結果
PCページのLighthouseの結果
そして2023年4月にPR TIMESのほぼ全ての ページをCloudFrontからFastlyへ移行しました https://developers.prtimes.jp/2023/04/18/prtimes-cdn-fastly/ 今回は こちらについて 話します!
今回の発表では • なぜ移行する必要があったのか • 移行するために対応したこと • 具体的な移行手順 • 移行して分かったFastlyの良いところ 今回の発表では
今回の発表では を紹介します
• なぜ移行する必要があったのか • 移行するために対応したこと • 具体的な移行手順 • 移行して分かったFastlyの良いところ
なぜ移行する必要があったのか Smarty テンプレート + jQueryで構築されたレガシーなフロントエンド をReactでリプレイスしていくプロジェクトが進行中 → 検索エンジンになるべく早くインデックスさせるために サーバーサイドレンダリングとその結果をキャッシュする仕組みが必要 →
VCLを使った柔軟なキャッシュ戦略を取ることができる Fastlyへの移行が必要不可欠
• なぜ移行する必要があったのか • 移行するために対応したこと • 具体的な移行手順 • 移行して分かったFastlyの良いところ
カスタムVCLを導入 Fastlyの大きな特徴であるVCLを使った柔軟な設定の強みを 活かすためにカスタムVCLを導入しました。 まず初めに Using VCL > Custom VCL にある
VCLのボイラープレートをそのままコピーして動作確認 しました。 その後、必要な要件に応じて様々な設定を追加しました。
VCLのライフサイクル
カスタムVCLのマクロについて カスタムVCL に含まれている #FASTLY recv のような コメントはマクロとして設定されており、 この部分にカスタムVCL外の設定が展開されます。 → そのため、設定を追加する場合はこのコメントより
前に書くとマクロに上書きされてしまう場合があります。
カスタムVCLのマクロについて ここにカスタムVCL外 の設定が展開される
#FASTLY hit から 展開された部分
マクロ展開後の VCL全体 バージョンごとの VCLの変更差分 設定を反映した後でVCLの差分やVCL全体を確認する
パスベースのルーティング設定 PR TIMESではprtimes.jpドメインのサブディレクトリに 別サーバーで動く複数のサービスがあります。 PR TIMES (/) PR TIMES Web
クリッピング (/webclipping) PR TIMES STORY (/story) PR TIMES MAGAZINE (/magazine) など
パスベースのルーティング設定 マクロに上書き されないように #FASTLY recv より下に記述
Cache-Controlヘッダーの設定 Fastlyを含め一般的なCDNではCache-Controlヘッダーなどの値を元に CDNでキャッシュするかどうかを判定します。 ここで注意する必要があるのがデフォルトのVCL設定だと • Cache-Controlヘッダーがない場合はキャッシュされる • Cache-Control: no-cacheはキャッシュされる ということです。
さらに、カスタムVCLを使わないデフォルトの状態だと • Cache-Control: no-storeもキャッシュされる という落とし穴もあります。
Cache-Controlヘッダーがない場合 HTTP は可能な限りキャッシュするように設計されているの で、Cache-Control が指定されていなくても、ある条件が 満たされればレスポンスは格納されて再利用されます。 これはヒューリスティックキャッシュと呼ばれます。 HTTP - HTTP
| MDN キャッシュ より引用
Cache-Controlヘッダーがない場合 ヒューリスティックキャッシュの有効期限はLast-Modified ヘッダなどの値を元に算出することが多いですが、 Fastlyでは3600秒をデフォルトの有効期限に設定しています。 (VCLから変更することも可能)
Cache-Control: no-cacheはキャッシュされる no-cache はキャッシュにレスポンスを保存することを許可 しますが、再利用する前に再検証することを要求します。 もし、「キャッシュさせない」の意味が実際には 「保存させない」であるなら、no-store が使用すべき ディレクティブです。 Cache-Control
- HTTP | MDN より引用
Cache-Control: no-cacheはキャッシュされる 再利用する前に再検証してくれるなら大丈夫じゃないの? と思うかもしれませんが、残念ながらFastlyでは no-cacheのときキャッシュの再検証をしてくれません! (再検証の仕組みを自力でカスタムVCLに実装すれば 実現は可能)
Cache-Control: no-storeもキャッシュされる場合がある カスタムVCLのボイラープレートを使っていない場合、 オリジンサーバーが Cache-Control: no-store を返しても キャッシュされてしまうことがあります。 if文の条件に no-storeが入っていない
Cache-Controlヘッダーの値によるCDNのキャッシュ可否 private max-age=0 s-maxage=0 no-store no-cache それ以外 Fastly (カスタムVCLあり) しない
しない する (再検証なし) する Fastly (カスタムVCLなし) しない する する (再検証なし) する CloudFront しない しない する (再検証あり) する
Cache-Controlヘッダーの挙動について これが想定通りの挙動なら大丈夫ですが、そうでない場合は 個人情報漏えいにもつながりかねない重要な設定です。 特にキャッシュされるはずのものがキャッシュされないこと よりキャッシュされないはずのものがキャッシュされること の方が重大なインシデントに繋がりやすいです。
Cache-Controlヘッダーの設定を変更 今回はアプリケーション側の修正箇所の多さと 対応漏れによるキャッシュ事故のリスクを考慮して • Cache-Control ヘッダーがない場合はキャッシュされない • Cache-Control: no-cache はキャッシュされない
となるようにカスタムVCLを変更しました。
Cache-Controlヘッダーの設定を変更 Cache-Control: no-cache の場合もキャッシュしない 変更後のVCL 変更前のVCL Cache-Control ヘッダーがない 場合はキャッシュしない
配信可能なオブジェクトのサイズ上限 (2020年6月17日以降に作成されたアカウントの場合) Fastlyで配信できるオブジェクトのサイズが最大20MBになっており、 これを超える場合は 503 Response object too large エラーが発生します。
これを回避するためには • セグメントキャッシュの利用 • オブジェクトサイズの上限引き上げ依頼 のいずれかを行う必要があります。
セグメントキャッシュの利用 セグメントキャッシュ = オブジェクトを分割してキャッシュできる機能 これを使うと配信可能なオブジェクトのサイズが無制限になります。 ただし • オリジンサーバーがRangeリクエストに対応している • 動的に生成されたコンテンツは不可
などの条件があるため注意が必要です。
オブジェクトサイズの上限引き上げ依頼 PR TIMESではプレスリリースのPDFダウンロード機能などで オブジェクトサイズが20MBを超える場合がありました。 しかしサーバーがRangeリクエストに対応しておらずセグメント キャッシュの利用は難しかったため、サポートに問い合わせて オブジェクトサイズの上限を50MBまで引き上げていただきまし た。
Cookie内のセッションIDのハッシュ化 Fastlyから出力するアクセスログのフォーマットは自由に 変更することができ、Cookieを追加することもできます。 しかしCookieにはユーザーのセッションIDが含まれている 場合があるため、万が一アクセスログが漏洩してしまった 場合に大きなセキュリティリスクになります。
Cookie内のセッションIDのハッシュ化 アクセスログに書き込む前にCookie内のセッションIDを ハッシュ化することで、万が一漏洩してしまった場合の リスクを抑えながらユーザーを識別できるようにしました。
Cookie内のセッションIDのハッシュ化 ログ出力の” ” 前 なので #FASTLY log よりも前に書く
メンテナンス画面の設定 データベースのバージョンアップ時など、サービス全体で メンテナンス画面を表示させるという要件もVCLを使って 簡単に実現できます。
メンテナンス画面の設定 (ディクショナリ) まずはメンテナンス状態の切り替え用のディクショナリを 作成します。 ディクショナリはバージョンを更新することなく変更する ことができます。
メンテナンス画面の設定 (HTMLファイル) Terraformを使っている場合、以下のようにしてメンテナンス用の HTMLファイルをカスタムVCL内に渡すことができます。
service_configディクショナリの maintenance が true なら 600エラーを発生させる (他のエラーと被らないように 存在しないステータスコード を使うのがおすすめ) メンテナンス画面の設定
(VCL)
600エラーが発生しているなら ステータスコードを503に設定して メンテナンスページを表示する 直接HTMLを書いてもOK メンテナンス画面の設定 (VCL)
メンテナンス画面の設定 600エラーを発生させるときのif文に条件を加えることで メンテナンス画面を表示させる条件を柔軟に変更できます。 • 特定のIPアドレスのみ通過させる • 特定のページのみメンテナンス画面を表示させる など
• なぜ移行する必要があったのか • 移行するために対応したこと • 具体的な移行手順 • 移行して分かったFastlyの良いところ
CDN Serviceの作成 まず初めにCDN Serviceを作成しました。 このとき先ほど紹介したカスタムVCLのボイラープレートを 有効化しておくと後で設定を変更するときに便利なので オススメです。
TLS証明書の取得 次に独自ドメインでHTTPSを使うためにTLS証明書を取得 しました。 外部で取得した証明書をインポートすることも可能ですが、 更新作業が不要なFastly TLSを使って取得するのがオススメ です。
TLS証明書の取得 Fastly TLSでは認証局を以下から選択できます。 • Let’s Encrypt : 無料の認証局 • Certainly
: Fastlyの提供する認証局 • GlobalSign : 有料の認証局 Let’s EncryptとCertainlyは追加料金なしで利用できます。 (無料アカウントなら2個、有料アカウントなら5個までで それ以降は1ドメインごとに$20/月)
/etc/hosts を使った動作確認 次にローカルマシンの /etc/hosts に以下のように追記して 動作確認を行いながらVCLの設定を変更しました。 151.101.1.55 prtimes.jp Fastly TLSで証明書を取得後に得られる
Anycast IPアドレス
本番環境でのFastlyへの移行 次に実際に本番環境のCDNをFastlyに切り替えていきますが、 Fastly上にキャッシュがまだないので全て一度に切り替えると オリジンサーバーに負荷がかかる可能性があります。 → Route53の加重ルーティング機能を使って 段階的に移行を行いました。
本番環境でのFastlyへの移行
本番環境でのFastlyへの移行
本番環境でのFastlyへの移行
本番環境でのFastlyへの移行
本番環境でのFastlyへの移行
• なぜ移行する必要があったのか • 移行するために対応したこと • 具体的な移行手順 • 移行して分かったFastlyの良いところ
VCLによる柔軟な設定ができる 先ほど紹介したパスベースのルーティング設定や セッションIDのハッシュ化、メンテナンス画面の設定など カスタムVCLを使ってCDNの動作を柔軟に変更することが できます。
キャッシュパージが高速かつ柔軟 キャッシュをパージする方法は • 単一URLのパージ • 特定のサロゲートキーの一括パージ • 全てのURLの一括パージ を選択でき、どれも非常に高速に実行できます。(1秒以下) また、サロゲートキーを使うことで特定のユーザーの画像
のみキャッシュパージするなどの要件が簡単に実現できます。
サポートが手厚い 今回の移行に伴いエンタープライズサポートを契約し、 移行のサポートをしていただきました。 VCLについてだけでなくTerraformのコードまで踏み込んで サポートいただきました。 また、運用後にエラーの発生している箇所について 能動的に改善提案をいただきとても助かりました。
最後に 今回あまり紹介できなかったImageOptimizerの活用事例なども 書いているのでぜひ開発者ブログも読んでみてください! https://developers.prtimes.jp/tag/fastly/ prtimes 開発者ブログ fastly