ようへいの日々精進XP

よかろうもん

2021 年 12 月 22 日 (水)

アクティビティ (今までの走行 (歩行) 距離)

https://pixe.la/v1/users/inokappa/graphs/fitbit-activity

Fitibit Charge2 のアクティビティから走行 (歩行) 距離を Fitbit Web API で取得して Pixela で草生やしている。色が濃くなれば濃くなる程強度が高い (歩行、走行距離が長い) ということで。実装の詳細はこちら

ジョギング

エアロバイクを 50 分。

レアジョブ

今朝も正蔵先生。「プリクラで髪の毛を追加できるか?」という話題で盛り上がった。

夕飯

【最終回】Infra Study 2nd #8「エンジニアのアウトプット」

エアロバイクを漕ぎながら、シャワーを浴びながら、ご飯を食べながら視聴した。

forkwell.connpass.com

Matz さんの基調講演に始まって、LT まで、すごく心が揺さぶられた。

やっぱり、何はなくとも、エンジニアじゃなくても、解っちゃいるけど、改めて、誰でもアウトプットは大切であることを痛感した。また、録画を見直したい。

2021 年 12 月 21 日 (火)

アクティビティ (今までの走行 (歩行) 距離)

https://pixe.la/v1/users/inokappa/graphs/fitbit-activity

Fitibit Charge2 のアクティビティから走行 (歩行) 距離を Fitbit Web API で取得して Pixela で草生やしている。色が濃くなれば濃くなる程強度が高い (歩行、走行距離が長い) ということで。実装の詳細はこちら

ジョギング

完全休養。また、右足に痛みがあって辛い。

レアジョブ

久しぶりに正蔵先生だった。

夕飯

2021 年 12 月 20 日 (月)

アクティビティ (今までの走行 (歩行) 距離)

https://pixe.la/v1/users/inokappa/graphs/fitbit-activity

Fitibit Charge2 のアクティビティから走行 (歩行) 距離を Fitbit Web API で取得して Pixela で草生やしている。色が濃くなれば濃くなる程強度が高い (歩行、走行距離が長い) ということで。実装の詳細はこちら

ジョギング

朝 5 時半に起きて、6 時過ぎからスタート。さすがにこの時期の 6 時過ぎは暗すぎた。

レアジョブ

今日も完全休養。明日は、久しぶりに正像先生。

夕飯

奥さんが納豆パスタがエラくお気に入りなので、今日も調子に乗って作ってみた。前回よりも美味しく出来たので良かった。

2021 年 12 月 19 日 (日)

アクティビティ (今までの走行 (歩行) 距離)

https://pixe.la/v1/users/inokappa/graphs/fitbit-activity

Fitibit Charge2 のアクティビティから走行 (歩行) 距離を Fitbit Web API で取得して Pixela で草生やしている。色が濃くなれば濃くなる程強度が高い (歩行、走行距離が長い) ということで。実装の詳細はこちら

ジョギング

完全休養。

レアジョブ

完全休養。

夕飯

平戸のお宿にて、満腹で絶品な夕飯だった。

2021 年 12 月 18 日 (土)

アクティビティ (今までの走行 (歩行) 距離)

https://pixe.la/v1/users/inokappa/graphs/fitbit-activity

Fitibit Charge2 のアクティビティから走行 (歩行) 距離を Fitbit Web API で取得して Pixela で草生やしている。色が濃くなれば濃くなる程強度が高い (歩行、走行距離が長い) ということで。実装の詳細はこちら

ジョギング

寒すぎた。

レアジョブ

今日も明日もお休み。

夕飯

久しぶりにお鍋。寒い日には鍋だなあ。

2021 年 12 月 17 日 (金)

アクティビティ (今までの走行 (歩行) 距離)

https://pixe.la/v1/users/inokappa/graphs/fitbit-activity

Fitibit Charge2 のアクティビティから走行 (歩行) 距離を Fitbit Web API で取得して Pixela で草生やしている。色が濃くなれば濃くなる程強度が高い (歩行、走行距離が長い) ということで。実装の詳細はこちら

ジョギング

今日はあまりにも寒かったし、腰やら足の具合もイマイチだったのでエアロバイク。

レアジョブ

今朝は、朝 7 時から val 先生だった。んー、満を持して臨んだのに全然しゃべれなかった...

夕飯

2021 年 12 月 16 日 (木)

アクティビティ (今までの走行 (歩行) 距離)

https://pixe.la/v1/users/inokappa/graphs/fitbit-activity

Fitibit Charge2 のアクティビティから走行 (歩行) 距離を Fitbit Web API で取得して Pixela で草生やしている。色が濃くなれば濃くなる程強度が高い (歩行、走行距離が長い) ということで。実装の詳細はこちら

ジョギング

レアジョブ

今朝は、朝 6 時半から正蔵先生。全然しゃべれなかった... 朝が早すぎたかな 😎

夕飯

JAWS-UG 福岡もくもく会 #54

今日もつづがなく開催。

jaws-ug-kyushu.doorkeeper.jp

ワイワイと雑談が楽しかった。

2021 年 12 月 15 日 (水)

アクティビティ (今までの走行 (歩行) 距離)

https://pixe.la/v1/users/inokappa/graphs/fitbit-activity

Fitibit Charge2 のアクティビティから走行 (歩行) 距離を Fitbit Web API で取得して Pixela で草生やしている。色が濃くなれば濃くなる程強度が高い (歩行、走行距離が長い) ということで。実装の詳細はこちら

ジョギング

完全休養。

レアジョブ

今朝は、朝 8 時から正蔵先生。今日も雑談で英会話が捗った。

夕飯

本格家庭風居酒屋ひろみで一杯。鯖みりんやら、鶏ささみとザーサイの和え物で美味しゅうございました。

Ruby biz グランプリ!

所属する YAMAP が Ruby biz グランプリを受賞!

素晴らしい!

急いで CloudFront コンテンツキャッシュの挙動について確認する 〜 最小 TTL の設定には気をつけたい 〜

これは

YAMAP エンジニア Advent Calendar 2021 の第 12 日目の記事にします。

qiita.com

経緯

今回、API レスポンスを CloudFront にキャッシュしようということになって、CloudFront のコンテンツキャッシュの挙動について確認する機会があったのでメモしておきます。

確認したい内容としては、以下の通りでした。

  • オリジンからの Cache-Control ヘッダの値によってキャッシュの挙動が変わるか
  • CloudFront の TTL 設定によって、キャッシュの挙動がどのように変わるか

これらの挙動については、以下の AWS ドキュメントに整理されており、自分で手を動かすまでもないかもしれませんが、自分は、ドキュメントを読んだだけではピンと来なかったので、今回、手を動かして確認してみることにしました。

docs.aws.amazon.com

尚、今回の記事では、「オリジンが Cache-Control: no-cache、no-store、および (または) private を返すパターン」のみを動作確認したいと思います。

f:id:inokara:20211215001519p:plain f:id:inokara:20211215001531p:plain

検証

とある API

YAMAP API のとある API エンドポイント (以後、/foo/bar) では、YAMAP 上のあるデータを返してくれます。パラメータを 2 つ指定することが可能で、1 つは、p= そして、もう一つは、キャッシュを制御する cache= です。

以下はサンプルリクエストです。

$ curl https://${API_ENDPOINT}/foo/bar?p=123
$ curl https://${API_ENDPOINT}/foo/bar?p=123&cache=1

cache= パラメータの有無で、以下のような違いがあります。

  • cache=0 を付与しない場合、レスポンスに cache-control: max-age=3600, public が付与されます
  • cache=0 を付与した場合、レスポンスに cache-control: max-age=0, private, must-revalidate が付与されます

ここで Cache-Control ヘッダについて

自分自身、Cache-Control ヘッダについて、名前しか聞いたことが無かったので、インターネット上のドキュメントを読みながら整理してみたいと思います。

参考にするドキュメントは、HTTP 技術資料の殿堂 (だと勝手に思っている) とも言える、MDN Web Docs です。

developer.mozilla.org

HTTP リクエストとレスポンスの両方でキャッシュを制御する為の設定 (文書内では「ディレクティブ」と書かれているので、以後はディレクティブと書く) が入っている HTTP ヘッダーが Cache-Control ヘッダーで、構文的には、以下のような決まりがあります。

  • 大文字小文字の区別は無いが、小文字が推奨される
  • 複数のディレクティブを定義することが出来るが、それらは、カンマで区切る
  • ディレクティブには、オプションの引数があり、トークンまたは quoted-string のどちらかで指定する

ディレクティブは、大別すると 3 つ (キャッシュ可能性、有効期限、再検証と再読み込み) にカテゴリ分けされています。全てのディレクティブについての説明を載せるのは、この記事の範疇を超えてしまうので、今回の記事に関係しそうなディレクティブのみを抜粋して転載します。

ディレクティブ 説明 (文書より引用)
public レスポンスが通常はキャッシュ可能でなくても、レスポンスをどのキャッシュにも格納することができます。
private レスポンスが通常はキャッシュ可能でなくても、ブラウザーのキャッシュにのみ格納することができます。レスポンスがどのキャッシュにも保存されないようにするには、代わりに no-store を使用してください。このディレクティブにはレスポンスがキャッシュに保存されないようにする効果はありません。
max-age= リソースが新しいとみなされる最長の時間です。 Expires とは異なり、このディレクティブはリクエスト時刻からの相対時間です。
must-revalidate 一度リソースが古くなると、キャッシュは元のサーバーでの検証が成功しない限り、古くなったコピーを使用してはならないことを示します。

冒頭に書いた、YAMAP の「とある API」のレスポンスを、上記の説明を踏まえて解釈すると、以下のように読み取れます。

$ curl https://${API_ENDPOINT}/foo/bar?p=123
...
cache-control: max-age=3600, public

このリクエストのレスポンスは、Cache-controlpublic が付与されている為、CDN 等にもキャッシュされている。また、max-age=3600 なので、キャッシュされているリソースの生存期間は 1 時間となる

$ curl https://${API_ENDPOINT}/foo/bar?p=123&cache=0
...
cache-control: max-age=0, private, must-revalidate

このリクエストのレスポンスは、Cache-controlprivate が付与されている為、ブラウザキャッシュのみに保存され (他のユーザーと共有されない)、リソースの生存期間は 0 ということで、常にリソース取得の為にサーバーにアクセスが発生される

「とある API」をキャッシュしてみる

本題に戻って

「とある API」を CloudFront でキャッシュしながら、キャッシュの挙動を確認してみたいと思います。

先述の通り、「とある API」は、リクエストパラメータによってオリジンから返却される Cache-Control ヘッダのディレクティブが異なる為、ディレクティブの設定に応じて、キャッシュの挙動を変える必要があります。

その辺りは、ドキュメントに記載されている通り、Cache-Control ヘッダのディレクティブを CloudFront が良しなに解釈してキャッシュの挙動を制御してくれますが、以下のパターン (再掲) で動作確認してみます。

  • オリジンからの Cache-Control ヘッダの値によってキャッシュの挙動が変わるか
  • CloudFront の TTL 設定によって、キャッシュの挙動がどのように変わるか

検証 (1) Cache-Control ヘッダの値によってキャッシュの挙動が変わるか

CloudFront のキャッシュ設定は、下図のような設定にしています。

f:id:inokara:20211215001617p:plain

「とある API」にアクセスしてみます。レスポンスヘッダの中から、cache-controlx-cache の値をチェックしてみます。

# 1 回目
$ curl https://${API_ENDPOINT}/foo/bar?p=123 -v 2>&1 | egrep 'cache-control|x-cache'
< cache-control: max-age=3600, public
< x-cache: Miss from cloudfront

# 2 回目
$ curl https://${API_ENDPOINT}/foo/bar?p=123 -v 2>&1 | egrep 'cache-control|x-cache'
< cache-control: max-age=3600, public
< x-cache: Hit from cloudfront

リクエストは、cache=1 が付与されていないので、オリジンのレスポンスには cache-control: max-age=3600, public が含まれている為、CloudFront でキャッシュされている (x-cacheHit from cloudfront となっている) ことが解ります。

一方で、オリジンレスポンスの Cache-Controlprivate が含まれている場合には、どのような挙動になるでしょうか。

# 1 回目
$ curl https://${API_ENDPOINT}/foo/bar?p=123&cache=1 -v 2>&1 | egrep 'cache-control|x-cache'
< cache-control: max-age=0, private, must-revalidate
< x-cache: Miss from cloudfront

# 2 回目
$ curl https://${API_ENDPOINT}/foo/bar?p=123&cache=1 -v 2>&1 | egrep 'cache-control|x-cache'
< cache-control: max-age=0, private, must-revalidate
< x-cache: Miss from cloudfront

リクエストには、cache=1 が付与されている為、オリジンレスポンスは cache-control: max-age=0, private, must-revalidate となり、これが CloudFront で解釈され、CloudFront ではキャッシュされていない (x-cache: Miss from cloudfront となっている)ことが解ります。

検証 (2) CloudFront の TTL 設定によって、キャッシュの挙動がどのように変わるか

試しに CloudFront のキャッシュ設定を下図のように変更してみます。

f:id:inokara:20211215001635p:plain

最小 TTL0 から 60 に変更してみます。最小 TTL0 以上にした場合、下図の通り、挙動が変わってきます。(再掲)

f:id:inokara:20211215001519p:plain f:id:inokara:20211215001531p:plain

オリジンレスポンスが cache-control: max-age=0, private, must-revalidate となるように、リクエストしてみて挙動を確認します。

# 1 回目
$ curl https://${API_ENDPOINT}/foo/bar?p=123&cache=1 -v 2>&1 | egrep 'cache-control|x-cache'
< cache-control: max-age=0, private, must-revalidate
< x-cache: Miss from cloudfront

# 2 回目
$ curl https://${API_ENDPOINT}/foo/bar?p=123&cache=1 -v 2>&1 | egrep 'cache-control|x-cache'
< cache-control: max-age=0, private, must-revalidate
< x-cache: Hit from cloudfront

おっと、CloudFront にキャッシュされている (x-cacheHit from cloudfront となっている) ことが確認出来ました。

ブラウザだけにキャッシュを想定してオリジンとなるアプリケーションを実装したとしても、CloudFront によって意図しないキャッシュが行われてしまうので、最小 TTL の設定には気をつけたいと思います。

以上

CloudFront コンテンツキャッシュの極一部の挙動について確認してみました。実際に手を動かすことで、これまでフワッとしていたことが明確になったので本当に良かったです。

2021 年 12 月 14 日 (火)

アクティビティ (今までの走行 (歩行) 距離)

https://pixe.la/v1/users/inokappa/graphs/fitbit-activity

Fitibit Charge2 のアクティビティから走行 (歩行) 距離を Fitbit Web API で取得して Pixela で草生やしている。色が濃くなれば濃くなる程強度が高い (歩行、走行距離が長い) ということで。実装の詳細はこちら

ジョギング

レアジョブ

朝 7 時から正蔵先生。今日も雑談で英会話が捗った。

夕飯

今日は鮭のムニエルを美味しく頂きました。

めちゃくちゃな話

一ヶ月くらい前から進行中のめちゃくちゃな話。ちょっと落ち着いたと思ったら、また先方からぶり返されて憂鬱な気持ち。