GAEのサービス間通信にはデフォルトのドメインを使うと速いという話
追記) サービス間通信に関わらず、東京リージョンではカスタムドメインを使うとレイテンシが増加
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に直接リクエストを送ることになる。
👩💻 ブラウザ ⇔ Go on GAE
一方で、Next.jsでサーバーサイドレンダリング(SSR)をすると、以下のようにGAEのサービス同士で通信が行われることになる。
👩💻 ブラウザ ⇔ 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
お察しの通り、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を使った方が早いという悲しみがあります。
貴重な情報ありがとうございます。恥ずかしながらドキュメントの該当の記述を見落としておりました。
追加で試してみたところ
*.r.appspot.com
に比べてカスタムドメインへのアクセスのレイテンシが大きいことが確認できました。us-central
のサービスで試してみても*.r.appspot.com
よりカスタムドメインの方がややレイテンシが大きくなりました。*r.appspot.com
とレイテンシがほとんど変わらないようでした。もう少し調査してみます。このあたりについての情報が探してもなかなかヒットしないのでコメント心より感謝します。