🚅

GAEのサービス間通信にはデフォルトのドメインを使うと速いという話

2021/03/23に公開
2

追記) サービス間通信に関わらず、東京リージョンではカスタムドメインを使うとレイテンシが増加

sinmetalさんにコメントで教えていただきました。

お察しの通り、Tokyo Regionを含むいくつかのRegionのApp EngineはCustom DomainでアクセスするとLatencyが増加します。
ドキュメントとしては https://cloud.google.com/appengine/docs/standard/ruby/mapping-custom-domains?hl=en に書いてあります。
確証はないですが、GoogleのネットワークのエッジポイントにあるGoogle Frontend Serverは、App EngineのCustom Domainの紐付けを持っておらず、us-central1に一度行ってしまうために、発生するLatencyなのではないかと思います。
そのため、Custom Domainでアクセスする場合はus-central1を使った方が早いという悲しみがあります。

個人的に追加でいくつか試してみました。

  • GAEを東京リージョンで使用した場合(サービス間通信に限らず)カスタムドメインに比べてGAEデフォルトの*.r.appspot.comドメインにアクセスしたときの方がレイテンシが小さかった。
  • ドキュメントには「カスタムドメインを使うとレイテンシが生じるリージョン」の一覧として載っていないus-centralで試した場合にも*.r.appspot.comの方がレイテンシが小さい傾向が見られた。
  • Cloud CDN(HTTPSロードバランサ)を使ってカスタムドメインを設定した場合は*.r.appspot.comとレイテンシがほとんど変わらなかった。

以下、最初に公開していた本文

Google App Engine(GAE)について、ググってもほとんどヒットしないが重要な点に気づいたので記事にしておく。

最近のWebサービスではバックエンド(API)とフロントエンドを分ける構成が多いと思う。例えばフロントエンドにはNext.js、バックエンドにはGoを使い、どちらもGAEで動かすとする。

クライアントサイドレンダリング(CSR)のときにはブラウザからGoのAPIに直接リクエストを送ることになる。

CSRのとき
👩‍💻 ブラウザ ⇔ Go on GAE

一方で、Next.jsでサーバーサイドレンダリング(SSR)をすると、以下のようにGAEのサービス同士で通信が行われることになる。

SSRのとき
👩‍💻 ブラウザ ⇔ Next.js on GAE ⇔ Go on GAE

GAEのサービス間通信にはカスタムドメインよりデフォルトのドメインを使った方が速い

普通はCSRでもSSRでもAPIリクエストには同じURLを使うことになると思う。APIサーバにapi.example.comというカスタムドメインをあてているなら、常にapi.example.comにリクエストを送るのが楽だ。

しかし個人的に試した結果、Next.jsやNuxt.jsのSSRでGAEのサービス間での通信が生じるときにはGAEデフォルトのドメインを使った方が高速ということが分かった。GAEのデフォルトのドメインはこういうやつ。

https://GCPのプロジェクト名.リージョンID.r.appspot.com

# 例えばGCPのプロジェクト名がfoo-bar、リージョンがasia-northeast1の場合はこんな感じになる
https://foo-bar.an.r.appspot.com

※ 他にもURLのパターンは色々ある(参考:リクエストのルーティング方法

どのくらい速くなったか

あくまでも個人的に試した結果だが、SSRのときに○○.r.appspot.comにリクエストを送るようにしただけで、全く同じ内容のページのレスポンスが100〜150msくらい速くなった。当然いろいろな条件によってこの数字は変わってくると思う。

なぜ速くなるのか

ドキュメントに載っていないので分からないが、GCP管理化のネットワークを通るようになったからとか? また、2020年2月のGAEのリリースノートにこんなことが書かれていた。

You can now include a region ID to help Google route your requests more efficiently and reliably.

https://○○.リージョンID.r.appspot.comの形式のURLだとGoogleがリクエストのルーティングを効率的にできるようだ。

axiosの設定例

例えばaxiosならbaseURLの値をサーバーとブラウザで切り替えれば良さそう。

const isServer = typeof window === "undefined";
const baseURL = "https://api.example.com";
const ssrBaseUrl = "https://foo-bar.an.r.appspot.com";

axios.create({
  baseURL: isServer ? ssrBaseUrl : baseUrl
})

Nuxt.jsのAxiosパッケージを使うならデフォルトでbrowserBaseURLを指定できるようになっているのでもっと綺麗に書ける。


軽い気持ちで試してみたのだが、まさかこれほど明らかにレスポンスが速くなるとは思わなかった。「フロントエンドとバックエンドの両方をGAEで動かしている」という方はぜひ試してみてほしい。

Discussion

sinmetalsinmetal

お察しの通り、Tokyo Regionを含むいくつかのRegionのApp EngineはCustom DomainでアクセスするとLatencyが増加します。
ドキュメントとしては https://cloud.google.com/appengine/docs/standard/ruby/mapping-custom-domains?hl=en に書いてあります。
確証はないですが、GoogleのネットワークのエッジポイントにあるGoogle Frontend Serverは、App EngineのCustom Domainの紐付けを持っておらず、us-central1に一度行ってしまうために、発生するLatencyなのではないかと思います。

そのため、Custom Domainでアクセスする場合はus-central1を使った方が早いという悲しみがあります。

catnosecatnose

貴重な情報ありがとうございます。恥ずかしながらドキュメントの該当の記述を見落としておりました。

追加で試してみたところ

  • サービス間通信に関わらず*.r.appspot.comに比べてカスタムドメインへのアクセスのレイテンシが大きいことが確認できました。
  • ドキュメントには載っていなかったus-centralのサービスで試してみても*.r.appspot.comよりカスタムドメインの方がややレイテンシが大きくなりました。
  • GCPのロードバランサにカスタムドメインを設定した場合は*r.appspot.comとレイテンシがほとんど変わらないようでした。

もう少し調査してみます。このあたりについての情報が探してもなかなかヒットしないのでコメント心より感謝します。