すでに何度が触れていますが、GCE HTTP(S) ロードバランサー が更にアップデートされました。同じく、 HTTP(S) ロードバランサー限定で Cloud CDN というサービスも有効となりました。

GCEでHTTPS負荷分散 SSL Termination – 続 カッコの付け方

GCP リージョン跨ぎロードバランサーの破壊力 – 続 カッコの付け方

HTTP(S) ロードバランサー追加機能

以前の記事で

  • 1つのIPアドレスで 80 & 443を Listen 出来ない

と書きましたがこれは解消?されているようです。この場合、エフェメラルではなく、静的なIPを1つ取得して、 80にも443にも指定すればOKです。これでよくある(AWS ELBのように) 1つのELBで 80/443 を両方通す設定が可能です。

20160626102416

また、この変更?により、http/httpsの違いによる x-forwarded-for の差は無くなりました(私の記憶が確かであれば)。かならず
[HTTP(S)バランサのIP] -> [多分SSLを解くナニカ] -> [自分でたてたinstance]
となります。この[SSLを解くナニカ]ですが、毎度アクセスするたびにIPアドレスが変わります。これから推測するに、かなりの数のインスタンスがSSL解きをやっているのだと思います。イメージはこんな感じ。

20160626115810

ネットワークロードバランサはDSRであるため、技術的に暖気不要なことは説明がつきます。
対して HTTP(S)はリバースプロキシ型となったため、HTTP/HTTPSいずれもターミネートする存在が必要です。ここかショボイと詰まってしまいますが、圧倒的な物量でカバーしていると推測します。

Cloud CDN

Cloud CDNとは、HTTP(S) ロードバランサー専用のCDN機能です。が、これは Google Cloud Storage (GCS)単体でも実現出来る、CDN機能をGCEにも応用したようなものらしいです。なので、

  • 静的コンテンツ(ccs,js,image)はGCSから配信(キャッシュのメタデータもちゃんとセットしている)
  • 動的コンテンツのみGCE + LBで配信

しているような健全なサイトであれば、正直微妙な機能です。GCS使ってれば、静的コンテンツは自動的にCDN配信ですから。

GCE側の実装

GCE側の設定としては超簡単です。

20160626105256

これで終了

キャッシュの有効期限とか

設定できません。オリジンがはき出すヘッダを厳守します。逆に言うと CloudFrontのように、オリジンヘッダを無視して勝手にキャッシュ保持期間を設定したり出来ません。

サーバ側の設定

問題はこれからです。下記はドキュメントの抜粋
https://cloud.google.com/cdn/docs/caching#cacheability

  • 下記条件を満たしていること
    • backend service が caching有効になってること、(上記のGCE側設定)
    • GET だけ
    • HTTPレスポンスコードは 200, 203, 300, 301, 302, 307, 410 のどれか
    • レスポンスヘッダに Cache-Control: public
    • レスポンスヘッダに Cache-Control: s-maxage, Cache-Control: max-ageExpires
    • まともな Date ヘッダ 未来の時間とかダメ
    • content-Length か、chunkなら Transfer-Encoding
  • 下記条件に当てはまるなら、キャッシュしない
    • Set-Cookie
    • データ部分が 4 MB超え
    • VaryAccept, Accept-Encoding, Origin 以外
    • Cache-Control: が no-store とか no-cache とか private
    • リクエストヘッダの時点で Cache-Control: no-store?

これらを満たす動的コンテンツってある?
ですがとりあえずやってみます。簡単なので一気に書くと apacheの設定で無理やり Cache-Controlヘッダを付けてやりました。

Header set Cache-Control "public, max-age=600"

apache再起動でOK。ものがphpだろうがなんだろうが、 Cache-Controlを付けます。検証用なので超雑。

動作確認

curl -i で試します。私の試したところ、エッジサーバ毎にAgeを個別に持っているように思います。ですので、数回叩かないとAgeが帰ってこないかもしれません。

$ curl -i http://xxx.yyyy.xxx.zzz/index.html
HTTP/1.1 200 OK
Date: Sun, 26 Jun 2016 02:15:35 GMT
Server: Apache/2.2.15 (CentOS)
Last-Modified: Sat, 25 Jun 2016 20:51:47 GMT
ETag: "21549-9-5362074a6e070"
Accept-Ranges: bytes
Content-Length: 9
Content-Type: text/html; charset=UTF-8
Via: 1.1 google
Cache-Control: public, max-age=600

hello

$ curl -i http://xxx.yyyy.xxx.zzz/index.html
HTTP/1.1 200 OK
Date: Sun, 26 Jun 2016 02:15:33 GMT
Server: Apache/2.2.15 (CentOS)
Last-Modified: Sat, 25 Jun 2016 20:51:47 GMT
ETag: "21549-9-5362074a6e070"
Accept-Ranges: bytes
Content-Length: 9
Content-Type: text/html; charset=UTF-8
Via: 1.1 google
Age: 5           <---- Ageきたー
Cache-Control: public, max-age=600

hello

invalidation

CDNといえば invalidationですが、Cloud CDNの場合はどうやるのでしょうか? GCSでは、GCS上のファイルを削除する・更新すると、CDN側のキャッシュも消えるらしい(あくまでも伝聞)のですが、GCEというかサーバではそんなこと出来ません。ので、ちゃんと invalidationの機能はあります。

20160626114650

パスに http://とか打つと

パスの先頭は「/」にしてください。「*」が使用できるのは、末尾の「/」の後のみです。また、パスには「?」と「#」を含めることはできません。

と教えてくれます。ワイルドカードもいけるんだ、ふーん。

まとめ

  • HTTP(S) ロードバランサーは 1IPで 80/443 Listen出来るようになった
  • Cloud CDNは HTTP(S) ロードバランサー Only
  • キャッシュ期間は調整出来ない、オリジンのレスポンスヘッダを順守
  • Invalidation機能はある、ワイルドカードも使える

元記事はこちら

GCE HTTP(S) 負荷分散と Cloud CDNを使う