Edge Worker PaaS の fly.io が面白い
なかなかよいおもちゃを見つけたので、紹介します。
fly.io は CDN Edge Worker で JavaScript に特化した PaaS です。既存のサービスで近いものだと CloudFlare Workers もしくは Lambda@Edge でしょうか。
アカウント登録をして、次のようなコマンドを叩くとエッジで動くアプリケーションを作成することができます。
npm install -g @fly/fly fly login # mkdir my-flyio; cd my-flyio fly new
最小コードはこんな感じ。CloudFlare Workers と同じような ServiceWorker 風と、Google Cloud Function 風の 2 つのパターンでワーカーを定義できます。
// index.js addEventListener('fetch', function (event) { event.respondWith(new Response('Redirecting', { headers: { 'Location': 'https://fly.io/docs/apps/' }, status: 302 } )) })
fly.io のここがいい
フロントエンドの最適化の行き着く先の解の一つ、それは「CDN Edge で HTML をキャッシュして返却する」というものです。そして、ある程度動的な JS をユースケースに応じて返却したい場合、 Edge で SSR を行って、一度実行した HTML はキャッシュする、という戦略が有効です。
JS の SSR は、残念ながら今後も必要な技術だと想定されています。しかし、コンテナ技術の発展で、Node の運用の敷居は前より下がりましたが、それでも Node を運用するのを躊躇するエンジニアの方も多いでしょう。
SSR や HTML Cache に対するこれらの懸念を、Edge Worker はまとめて払拭できます。
- 必然的にPaaS なのでフルマネージド
- レスポンス最適化のために Edge Cache で HTML を返せる
- SSR は複雑な処理なので、ほぼフルスペックの Node がいる必要がある
また、SSR / BFF 特有の事情として、次のような要求があります。
- HTML をキャッシュする場合、セッション情報に触れないほうが安全に SSR できる
- SSR の主な需要は大雑把なファーストビューの最適化と、 GoogleBOT 向けの情報を構築することなので、セッションに触れる必要はない
- 起動後にリバースプロキシとして動いて API オーケストレーションを行う
イニシャルビュー最適化で、すべてのリクエストに対してセッション情報付きで SSR するのを要求する人もいますが、運用事故を避けたり、キャッシュ最適化やパフォーマンスチューンまで考えると、この辺が現実的な落としどころだと思います。
つまりは BFF (Backend for Frontend) と呼ばれていた層の一部を地理的に最適化される Edge Location に持ってくることができます。
そして、キャッシュを扱う以上、それなりに KVS を扱いたいわけで、他のサービスではなく fly.io が優れてるのは、この辺のために便利なパーツが一通り揃っていることです。
@fly/cache
: リージョン単位の揮発する KVS@fly/cache/global
: 永続化されるグローバルな KVS@fly/db
: 永続化されたグローバルな簡易ストレージ(Mongo 風?)@fly/static
: 簡易アセットサーバー@fly/fetch/mount
簡易ルーター@fly/fetch/proxy
簡易リバースプロキシ- varnish surrogate key のような、タグによる Cache Invalidation
varnish surrogate key による Cache Invalidation が個人的に一番欲しかったやつで、現状他の CDN だと fastly ぐらいしかこの機能を持っていませんでした。
https://book.varnish-software.com/4.0/chapters/Cache_Invalidation.html
各種ストレージを使ってみた感じ、それぞれは本格的なものではないのですが、アプリケーションサーバーへ到達する前の エッジロケーションにこれがある、ということが大事で、とくに各種キャッシュと簡易アセットサーバー、簡易ルータがあるので、頑張れば Edge で完結するアプリケーション層として動くことすら可能です。
作ってみた
というわけで、簡単な掲示板アプリを作ってみました。各ページはその Edge ではじめてときだけ SSR され、それ以降はキャッシュされた HTML を返却します。初期化以降は CSR で動きます。
https://grave-crowd-822.edgeapp.net
ソースはここ
https://github.com/mizchi/flyio-playground/tree/master/examples/react-ssr
主に React + react-router + styled-components での SSR と、 fly/db に書き込みの内容を永続化して、 fly/cache で SSR 済み HTML をキャッシュしています。next.js などは使わず手作業で無理矢理 isomorphic にしてるので、コードの見通しは悪いです。あとでどうにかする…
作ってみた感想
- node エンジニアなら特に迷うところサッと作れる
- ローカルでほぼサーバーと同等のものが動くので開発が楽 (lambda/cloud function はここが微妙)
- GitHubにソースが公開されてるので最悪これを自分でホスティングすればいいという安心感がある
- express (node http) 互換ではなく、コールバックが
(req, res) => {}
ではなく、(req) => new Response(...)
みたいな形式 - API ドキュメントがまだまだふわっとしている
- 独自の v8 でビルドされていて、微妙に実装されてないものがある (crypto 周りで動かないモジュールがあった)
fly/db
は、本当にただのおもちゃなので、信用しないほうがいい… (query や scan 相当のものもないし、列挙も出来ない…)- 本番環境での fly/cache/global への書き込みはそれなりに遅い
複雑なストレージを持つようなものではないので、これ一つで完結する、というものではありません。
参考になるリソース
- 公式 API ドキュメント https://fly.io/docs/apps/api/index.html
- GitHub の Examples https://github.com/superfly/fly/tree/master/examples
examples 眺めながら、公式ドキュメントを読みつつ、わからなかったら GitHub で実装を読む、という感じでだいたいやりたいことをやれました。
料金
- $25 の無料枠
- 有料の場合、最低月 $10 から
超大規模想定で適当に試算してみても $100 超えるのは難しそう
で、本格的に使っていいの?
ぶっちゃけリリース直後なので、なんとも言えません。人柱募集したいところ。
とりあえずは、Edge Worker 使った際のアーキテクチャを考察するための実験場として使うのがいいんじゃないでしょうか。ユーザーが増えて、実質 SLA どのぐらいか判明したら、プロダクションに突っ込むかどうか考えれば良さそう。
cloudflare も Edge Worker というよりは Serverless として Edge Worker 市場に参入するぞ!みたいなことを言い出してるので、こっちも注視したいです。
Node.js エンジニアの活路としての Edge Side
前々から思っていたこととして、フロントエンドとサーバーサイドの間に、 エッジサイドのエンジニアという職域がうまれるんじゃないかと想像しています。先に述べたように API オーケストレーション+SSR を行う Node BFF がここに位置するのではないか、と思っています。
日本においては node.js エンジニアは(SFなどの海外と比べて)あまりサーバーサイドでシェアを取れませんでしたが、まともな ORM がない Node 一本で行くのは僕もちょっと厳しいと思っていて、Node が本当に生きるのは、ブラウザと緊密に連携する前段の、Edge Side なんじゃないかと考えています。
Edge Workers は単なるパフォーマンス要件を満たす選択だけではなく、BFF ベストプラクティスとしての活用があると思っています。SPA を何年も作ってきましたが SPA をフルに運用するには、やはりフロントエンドエンジニアが握る BFF が不可欠だという気持ちがあります。
という感じでみなさんも fly.io で遊んでみてはいかがでしょうか。
ちょっと前に Edge ヘヴィーなフロントエンドのアーキテクチャの考察をしたので、こちらもどうぞ